├── bitmapscaler ├── .gitignore ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ ├── cpp │ │ ├── lib │ │ │ ├── x86 │ │ │ │ ├── libhwy.a │ │ │ │ └── libyuv.a │ │ │ ├── x86_64 │ │ │ │ ├── libhwy.a │ │ │ │ └── libyuv.a │ │ │ ├── arm64-v8a │ │ │ │ ├── libhwy.a │ │ │ │ └── libyuv.a │ │ │ └── armeabi-v7a │ │ │ │ ├── libhwy.a │ │ │ │ └── libyuv.a │ │ ├── RGBAlpha.h │ │ ├── libyuv │ │ │ ├── libyuv │ │ │ │ ├── version.h │ │ │ │ ├── rotate_argb.h │ │ │ │ ├── scale_rgb.h │ │ │ │ ├── scale_uv.h │ │ │ │ ├── basic_types.h │ │ │ │ ├── scale_argb.h │ │ │ │ ├── compare.h │ │ │ │ ├── cpu_id.h │ │ │ │ ├── compare_row.h │ │ │ │ ├── mjpeg_decoder.h │ │ │ │ ├── convert_from.h │ │ │ │ ├── rotate.h │ │ │ │ ├── rotate_row.h │ │ │ │ ├── video_common.h │ │ │ │ ├── convert_from_argb.h │ │ │ │ └── scale.h │ │ │ └── libyuv.h │ │ ├── JniExceptions.h │ │ ├── Rgb1010102toF16.h │ │ ├── JniExceptions.cpp │ │ ├── HalfFloats.h │ │ ├── CopyUnaligned.h │ │ ├── hwy │ │ │ ├── timer.h │ │ │ ├── highway_export.h │ │ │ ├── print.h │ │ │ ├── ops │ │ │ │ └── tuple-inl.h │ │ │ ├── cache_control.h │ │ │ ├── robust_statistics.h │ │ │ ├── aligned_allocator.h │ │ │ ├── detect_compiler_arch.h │ │ │ └── foreach_target.h │ │ ├── XScaler.h │ │ ├── CMakeLists.txt │ │ ├── BitmapScaler.cpp │ │ ├── HalfFloats.cpp │ │ ├── CopyUnaligned.cpp │ │ ├── Rgb1010102toF16.cpp │ │ └── RGBAlpha.cpp │ │ └── java │ │ └── com │ │ └── t8rin │ │ └── bitmapscaler │ │ ├── ScaleMode.kt │ │ ├── BitmapScaler.kt │ │ └── LockPixelsException.kt └── build.gradle.kts ├── jitpack.yml ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── settings.gradle.kts ├── README.md ├── LICENSE.md ├── gradle.properties ├── gradlew.bat ├── deps.sh └── gradlew /bitmapscaler/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /jitpack.yml: -------------------------------------------------------------------------------- 1 | jdk: 2 | - openjdk17 -------------------------------------------------------------------------------- /bitmapscaler/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/x86/libhwy.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/x86/libhwy.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/x86/libyuv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/x86/libyuv.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/x86_64/libhwy.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/x86_64/libhwy.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/x86_64/libyuv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/x86_64/libyuv.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/arm64-v8a/libhwy.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/arm64-v8a/libhwy.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/arm64-v8a/libyuv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/arm64-v8a/libyuv.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/armeabi-v7a/libhwy.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/armeabi-v7a/libhwy.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/lib/armeabi-v7a/libyuv.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/T8RIN/BitmapScaler/HEAD/bitmapscaler/src/main/cpp/lib/armeabi-v7a/libyuv.a -------------------------------------------------------------------------------- /bitmapscaler/src/main/java/com/t8rin/bitmapscaler/ScaleMode.kt: -------------------------------------------------------------------------------- 1 | package com.t8rin.bitmapscaler 2 | 3 | enum class ScaleMode { 4 | Bilinear, 5 | Nearest, 6 | Cubic, 7 | Mitchell, 8 | Lanczos, 9 | CatmullRom, 10 | Hermite, 11 | BSpline, 12 | Hann 13 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sat Jan 06 18:43:16 MSK 2024 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | .cxx 15 | local.properties 16 | .idea 17 | *.apk 18 | .cxx 19 | **/.cxx 20 | *.aab 21 | build 22 | .idea 23 | /app/release/output-metadata.json 24 | -------------------------------------------------------------------------------- /settings.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | pluginManagement { 4 | repositories { 5 | google() 6 | mavenCentral() 7 | gradlePluginPortal() 8 | } 9 | } 10 | dependencyResolutionManagement { 11 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 12 | repositories { 13 | google() 14 | mavenCentral() 15 | } 16 | } 17 | 18 | rootProject.name = "BitmapScaler" 19 | include(":bitmapscaler") 20 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/RGBAlpha.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Radzivon Bartoshyk on 06/11/2023. 3 | // 4 | 5 | #ifndef JXLCODER_RGBALPHA_H 6 | #define JXLCODER_RGBALPHA_H 7 | 8 | #include 9 | 10 | namespace coder { 11 | void UnpremultiplyRGBA(const uint8_t *src, int srcStride, 12 | uint8_t *dst, int dstStride, int width, 13 | int height); 14 | 15 | void PremultiplyRGBA(const uint8_t *src, int srcStride, 16 | uint8_t *dst, int dstStride, int width, 17 | int height); 18 | } 19 | 20 | #endif //JXLCODER_RGBALPHA_H 21 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_VERSION_H_ 12 | #define INCLUDE_LIBYUV_VERSION_H_ 13 | 14 | #define LIBYUV_VERSION 1823 15 | 16 | #endif // INCLUDE_LIBYUV_VERSION_H_ 17 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/java/com/t8rin/bitmapscaler/BitmapScaler.kt: -------------------------------------------------------------------------------- 1 | package com.t8rin.bitmapscaler 2 | 3 | import android.graphics.Bitmap 4 | import androidx.annotation.Keep 5 | 6 | @Keep 7 | object BitmapScaler { 8 | 9 | fun scale( 10 | bitmap: Bitmap, 11 | dstWidth: Int, 12 | dstHeight: Int, 13 | scaleMode: ScaleMode 14 | ): Bitmap = scaleImpl( 15 | bitmap = bitmap, 16 | dstWidth = dstWidth, 17 | dstHeight = dstHeight, 18 | scaleMode = scaleMode.ordinal + 1 19 | ) 20 | 21 | private external fun scaleImpl( 22 | bitmap: Bitmap, 23 | dstWidth: Int, 24 | dstHeight: Int, 25 | scaleMode: Int 26 | ): Bitmap 27 | 28 | init { 29 | System.loadLibrary("bitmapscaler") 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bitmap Scaler for Android API 14+ 2 | 3 | This BitmapScaler with different scaling algorhytms based on jxl-coder from awxkee can upscale or downscale bitmaps with 8 options: 4 | * Bilinear 5 | * Nearest Neighbour 6 | * Bicubic 7 | * Mitchell 8 | * Lanczos 9 | * Catmull 10 | * Hermite 11 | * Spline 12 | * Hann 13 | 14 | 15 | # Add Jitpack repository 16 | 17 | ```kotlin 18 | repositories { 19 | maven { setUrl("https://jitpack.io") } 20 | } 21 | ``` 22 | 23 | ```kotlin 24 | implementation("com.github.t8rin:bitmap-scaler:1.1.1") 25 | ``` 26 | 27 | # Self-build 28 | 29 | ## Requirements 30 | 31 | - ndk 32 | - ninja 33 | - cmake 34 | - nasm 35 | 36 | **All commands are require the NDK path set by NDK_PATH environment variable** 37 | 38 | * If you wish to build for **x86** you have to add a **$INCLUDE_X86** environment variable for 39 | example:* 40 | 41 | ```shell 42 | NDK_PATH=/path/to/ndk INCLUDE_X86=yes bash build_jxl.sh 43 | ``` 44 | 45 | # Copyrights 46 | 47 | This library created with [jxl-coder](https://github.com/awxkee/jxl-coder) sources 48 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Radzivon Bartoshyk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_H_ 12 | #define INCLUDE_LIBYUV_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/compare.h" 16 | #include "libyuv/convert.h" 17 | #include "libyuv/convert_argb.h" 18 | #include "libyuv/convert_from.h" 19 | #include "libyuv/convert_from_argb.h" 20 | #include "libyuv/cpu_id.h" 21 | #include "libyuv/mjpeg_decoder.h" 22 | #include "libyuv/planar_functions.h" 23 | #include "libyuv/rotate.h" 24 | #include "libyuv/rotate_argb.h" 25 | #include "libyuv/row.h" 26 | #include "libyuv/scale.h" 27 | #include "libyuv/scale_argb.h" 28 | #include "libyuv/scale_row.h" 29 | #include "libyuv/scale_uv.h" 30 | #include "libyuv/version.h" 31 | #include "libyuv/video_common.h" 32 | 33 | #endif // INCLUDE_LIBYUV_H_ 34 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/rotate_argb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_ROTATE_ARGB_H_ 12 | #define INCLUDE_LIBYUV_ROTATE_ARGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/rotate.h" // For RotationMode. 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | // Rotate ARGB frame 23 | LIBYUV_API 24 | int ARGBRotate(const uint8_t* src_argb, 25 | int src_stride_argb, 26 | uint8_t* dst_argb, 27 | int dst_stride_argb, 28 | int src_width, 29 | int src_height, 30 | enum RotationMode mode); 31 | 32 | #ifdef __cplusplus 33 | } // extern "C" 34 | } // namespace libyuv 35 | #endif 36 | 37 | #endif // INCLUDE_LIBYUV_ROTATE_ARGB_H_ 38 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Kotlin code style for this project: "official" or "obsolete": 19 | kotlin.code.style=official 20 | # Enables namespacing of each library's R class so that its R class includes only the 21 | # resources declared in the library itself and none from the library's dependencies, 22 | # thereby reducing the size of the R class for that library 23 | android.nonTransitiveRClass=true -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/scale_rgb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_RGB_H_ 12 | #define INCLUDE_LIBYUV_SCALE_RGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/scale.h" // For FilterMode 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | // RGB can be RAW, RGB24 or YUV24 23 | // RGB scales 24 bit images by converting a row at a time to ARGB 24 | // and using ARGB row functions to scale, then convert to RGB. 25 | // TODO(fbarchard): Allow input/output formats to be specified. 26 | LIBYUV_API 27 | int RGBScale(const uint8_t* src_rgb, 28 | int src_stride_rgb, 29 | int src_width, 30 | int src_height, 31 | uint8_t* dst_rgb, 32 | int dst_stride_rgb, 33 | int dst_width, 34 | int dst_height, 35 | enum FilterMode filtering); 36 | 37 | #ifdef __cplusplus 38 | } // extern "C" 39 | } // namespace libyuv 40 | #endif 41 | 42 | #endif // INCLUDE_LIBYUV_SCALE_UV_H_ 43 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/java/com/t8rin/bitmapscaler/LockPixelsException.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 23/9/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | package com.t8rin.bitmapscaler 30 | 31 | import androidx.annotation.Keep 32 | 33 | @Keep 34 | class LockPixelsException : Exception("Can't lock bitmap pixels") -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/scale_uv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_UV_H_ 12 | #define INCLUDE_LIBYUV_SCALE_UV_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/scale.h" // For FilterMode 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | LIBYUV_API 23 | int UVScale(const uint8_t* src_uv, 24 | int src_stride_uv, 25 | int src_width, 26 | int src_height, 27 | uint8_t* dst_uv, 28 | int dst_stride_uv, 29 | int dst_width, 30 | int dst_height, 31 | enum FilterMode filtering); 32 | 33 | // Scale a 16 bit UV image. 34 | // This function is currently incomplete, it can't handle all cases. 35 | LIBYUV_API 36 | int UVScale_16(const uint16_t* src_uv, 37 | int src_stride_uv, 38 | int src_width, 39 | int src_height, 40 | uint16_t* dst_uv, 41 | int dst_stride_uv, 42 | int dst_width, 43 | int dst_height, 44 | enum FilterMode filtering); 45 | 46 | #ifdef __cplusplus 47 | } // extern "C" 48 | } // namespace libyuv 49 | #endif 50 | 51 | #endif // INCLUDE_LIBYUV_SCALE_UV_H_ 52 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/JniExceptions.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 04/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #ifndef JXLCODER_JNIEXCEPTIONS_H 30 | #define JXLCODER_JNIEXCEPTIONS_H 31 | 32 | #include 33 | #include 34 | 35 | 36 | jint throwPixelsException(JNIEnv *env); 37 | jint throwException(JNIEnv *env, std::string& msg); 38 | 39 | int androidOSVersion(); 40 | 41 | #endif //JXLCODER_JNIEXCEPTIONS_H 42 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/Rgb1010102toF16.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 05/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #ifndef JXLCODER_RGB1010102TOF16_H 30 | #define JXLCODER_RGB1010102TOF16_H 31 | 32 | #include 33 | 34 | namespace coder { 35 | void ConvertRGBA1010102toF16(const uint8_t *src, int srcStride, uint16_t *dst, int dstStride, 36 | int width, int height); 37 | } 38 | 39 | #endif //JXLCODER_RGB1010102TOF16_H 40 | -------------------------------------------------------------------------------- /bitmapscaler/build.gradle.kts: -------------------------------------------------------------------------------- 1 | @file:Suppress("UnstableApiUsage") 2 | 3 | plugins { 4 | id("com.android.library") 5 | id("org.jetbrains.kotlin.android") 6 | id("maven-publish") 7 | } 8 | 9 | afterEvaluate { 10 | publishing { 11 | publications { 12 | create("mavenJava") { 13 | groupId = "com.github.t8rin" 14 | artifactId = "bitmap-scaler" 15 | version = "1.1.2" 16 | from(components["release"]) 17 | } 18 | } 19 | } 20 | } 21 | 22 | android { 23 | namespace = "com.t8rin.bitmapscaler" 24 | compileSdk = 34 25 | 26 | defaultConfig { 27 | minSdk = 14 28 | 29 | externalNativeBuild { 30 | cmake { 31 | ndkVersion = "26.1.10909125" 32 | cppFlags.add("-std=c++20") 33 | abiFilters += setOf("armeabi-v7a", "arm64-v8a", "x86_64", "x86") 34 | } 35 | } 36 | 37 | publishing { 38 | singleVariant("release") { 39 | withSourcesJar() 40 | withJavadocJar() 41 | } 42 | } 43 | } 44 | 45 | sourceSets.named("main") { 46 | this.jniLibs { 47 | this.srcDir("src/main/cpp/lib") 48 | } 49 | } 50 | 51 | externalNativeBuild { 52 | cmake { 53 | path("src/main/cpp/CMakeLists.txt") 54 | version = "3.22.1" 55 | } 56 | } 57 | compileOptions { 58 | sourceCompatibility = JavaVersion.VERSION_17 59 | targetCompatibility = JavaVersion.VERSION_17 60 | } 61 | kotlinOptions { 62 | jvmTarget = "17" 63 | } 64 | } 65 | 66 | dependencies { 67 | implementation("androidx.core:core-ktx:1.12.0") 68 | } -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/JniExceptions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 04/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include "JniExceptions.h" 30 | #include 31 | 32 | jint throwPixelsException(JNIEnv *env) { 33 | jclass exClass; 34 | exClass = env->FindClass("com/t8rin/bitmapscaler/LockPixelsException"); 35 | return env->ThrowNew(exClass, ""); 36 | } 37 | 38 | jint throwException(JNIEnv *env, std::string& msg) { 39 | jclass exClass; 40 | exClass = env->FindClass("java/lang/Exception"); 41 | return env->ThrowNew(exClass, msg.c_str()); 42 | } 43 | 44 | int androidOSVersion() { 45 | return android_get_device_api_level(); 46 | } -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/HalfFloats.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 04/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #ifndef JXLCODER_HALFFLOATS_H 30 | #define JXLCODER_HALFFLOATS_H 31 | 32 | #include 33 | #include "half.hpp" 34 | 35 | #if HAVE_NEON 36 | void RgbaF32ToF16Neon(const float *src, int srcStride, uint16_t *dst, int dstStride, 37 | int width, int height) ; 38 | #endif 39 | 40 | namespace coder { 41 | void RgbaF32ToF16(const float *src, int srcStride, uint16_t *dst, int dstStride, int width, 42 | int height); 43 | } 44 | 45 | float half_to_float(const uint16_t x); 46 | 47 | uint16_t float_to_half(const float x); 48 | 49 | #endif //JXLCODER_HALFFLOATS_H 50 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/CopyUnaligned.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 12/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #ifndef JXL_COPYUNALIGNEDRGBA_H 30 | #define JXL_COPYUNALIGNEDRGBA_H 31 | 32 | #include 33 | 34 | namespace coder { 35 | void 36 | CopyUnalignedRGBA(const uint8_t *__restrict__ src, int srcStride, 37 | uint8_t *__restrict__ dst,int dstStride, 38 | int width,int height, int pixelSize); 39 | 40 | void 41 | CopyUnalignedRGB565(const uint8_t *__restrict__ src, int srcStride, uint8_t *__restrict__ dst, 42 | int dstStride, int width, 43 | int height); 44 | } 45 | 46 | #endif //JXL_COPYUNALIGNEDRGBA_H 47 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/timer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_TIMER_H_ 17 | #define HIGHWAY_HWY_TIMER_H_ 18 | 19 | // Platform-specific timer functions. Provides Now() and functions for 20 | // interpreting and converting the timer-inl.h Ticks. 21 | 22 | #include 23 | 24 | #include "hwy/highway_export.h" 25 | 26 | namespace hwy { 27 | namespace platform { 28 | 29 | // Returns current timestamp [in seconds] relative to an unspecified origin. 30 | // Features: monotonic (no negative elapsed time), steady (unaffected by system 31 | // time changes), high-resolution (on the order of microseconds). 32 | // Uses InvariantTicksPerSecond and the baseline version of timer::Start(). 33 | HWY_DLLEXPORT double Now(); 34 | 35 | // Functions for use with timer-inl.h: 36 | 37 | // Returns whether it is safe to call timer::Stop without executing an illegal 38 | // instruction; if false, fills cpu100 (a pointer to a 100 character buffer) 39 | // with the CPU brand string or an empty string if unknown. 40 | HWY_DLLEXPORT bool HaveTimerStop(char* cpu100); 41 | 42 | // Returns tick rate, useful for converting timer::Ticks to seconds. Invariant 43 | // means the tick counter frequency is independent of CPU throttling or sleep. 44 | // This call may be expensive, callers should cache the result. 45 | HWY_DLLEXPORT double InvariantTicksPerSecond(); 46 | 47 | // Returns ticks elapsed in back to back timer calls, i.e. a function of the 48 | // timer resolution (minimum measurable difference) and overhead. 49 | // This call is expensive, callers should cache the result. 50 | HWY_DLLEXPORT uint64_t TimerResolution(); 51 | 52 | } // namespace platform 53 | } // namespace hwy 54 | 55 | #endif // HIGHWAY_HWY_TIMER_H_ 56 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/highway_export.h: -------------------------------------------------------------------------------- 1 | // Pseudo-generated file to handle both cmake & bazel build system. 2 | 3 | // Initial generation done using cmake code: 4 | // include(GenerateExportHeader) 5 | // generate_export_header(hwy EXPORT_MACRO_NAME HWY_DLLEXPORT EXPORT_FILE_NAME 6 | // hwy/highway_export.h) 7 | // code reformatted using clang-format --style=Google 8 | 9 | #ifndef HWY_DLLEXPORT_H 10 | #define HWY_DLLEXPORT_H 11 | 12 | #if !defined(HWY_SHARED_DEFINE) 13 | #define HWY_DLLEXPORT 14 | #define HWY_CONTRIB_DLLEXPORT 15 | #define HWY_TEST_DLLEXPORT 16 | #else // !HWY_SHARED_DEFINE 17 | 18 | #ifndef HWY_DLLEXPORT 19 | #if defined(hwy_EXPORTS) 20 | /* We are building this library */ 21 | #ifdef _WIN32 22 | #define HWY_DLLEXPORT __declspec(dllexport) 23 | #else 24 | #define HWY_DLLEXPORT __attribute__((visibility("default"))) 25 | #endif 26 | #else // defined(hwy_EXPORTS) 27 | /* We are using this library */ 28 | #ifdef _WIN32 29 | #define HWY_DLLEXPORT __declspec(dllimport) 30 | #else 31 | #define HWY_DLLEXPORT __attribute__((visibility("default"))) 32 | #endif 33 | #endif // defined(hwy_EXPORTS) 34 | #endif // HWY_DLLEXPORT 35 | 36 | #ifndef HWY_CONTRIB_DLLEXPORT 37 | #if defined(hwy_contrib_EXPORTS) 38 | /* We are building this library */ 39 | #ifdef _WIN32 40 | #define HWY_CONTRIB_DLLEXPORT __declspec(dllexport) 41 | #else 42 | #define HWY_CONTRIB_DLLEXPORT __attribute__((visibility("default"))) 43 | #endif 44 | #else // defined(hwy_contrib_EXPORTS) 45 | /* We are using this library */ 46 | #ifdef _WIN32 47 | #define HWY_CONTRIB_DLLEXPORT __declspec(dllimport) 48 | #else 49 | #define HWY_CONTRIB_DLLEXPORT __attribute__((visibility("default"))) 50 | #endif 51 | #endif // defined(hwy_contrib_EXPORTS) 52 | #endif // HWY_CONTRIB_DLLEXPORT 53 | 54 | #ifndef HWY_TEST_DLLEXPORT 55 | #if defined(hwy_test_EXPORTS) 56 | /* We are building this library */ 57 | #ifdef _WIN32 58 | #define HWY_TEST_DLLEXPORT __declspec(dllexport) 59 | #else 60 | #define HWY_TEST_DLLEXPORT __attribute__((visibility("default"))) 61 | #endif 62 | #else // defined(hwy_test_EXPORTS) 63 | /* We are using this library */ 64 | #ifdef _WIN32 65 | #define HWY_TEST_DLLEXPORT __declspec(dllimport) 66 | #else 67 | #define HWY_TEST_DLLEXPORT __attribute__((visibility("default"))) 68 | #endif 69 | #endif // defined(hwy_test_EXPORTS) 70 | #endif // HWY_TEST_DLLEXPORT 71 | 72 | #endif // !HWY_SHARED_DEFINE 73 | 74 | #endif /* HWY_DLLEXPORT_H */ 75 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/print.h: -------------------------------------------------------------------------------- 1 | // Copyright 2022 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HWY_PRINT_H_ 17 | #define HWY_PRINT_H_ 18 | 19 | // Helpers for printing vector lanes. 20 | 21 | #include 22 | #include 23 | 24 | #include "hwy/base.h" 25 | #include "hwy/highway_export.h" 26 | 27 | namespace hwy { 28 | 29 | namespace detail { 30 | 31 | // For implementing value comparisons etc. as type-erased functions to reduce 32 | // template bloat. 33 | struct TypeInfo { 34 | size_t sizeof_t; 35 | bool is_float; 36 | bool is_signed; 37 | bool is_bf16; 38 | }; 39 | 40 | template 41 | HWY_INLINE TypeInfo MakeTypeInfo() { 42 | TypeInfo info; 43 | info.sizeof_t = sizeof(T); 44 | info.is_float = IsFloat(); 45 | info.is_signed = IsSigned(); 46 | info.is_bf16 = IsSame(); 47 | return info; 48 | } 49 | 50 | HWY_DLLEXPORT void TypeName(const TypeInfo& info, size_t N, char* string100); 51 | HWY_DLLEXPORT void ToString(const TypeInfo& info, const void* ptr, 52 | char* string100); 53 | 54 | HWY_DLLEXPORT void PrintArray(const TypeInfo& info, const char* caption, 55 | const void* array_void, size_t N, 56 | size_t lane_u = 0, size_t max_lanes = 7); 57 | 58 | } // namespace detail 59 | 60 | template 61 | HWY_NOINLINE void PrintValue(T value) { 62 | char str[100]; 63 | detail::ToString(hwy::detail::MakeTypeInfo(), &value, str); 64 | fprintf(stderr, "%s,", str); 65 | } 66 | 67 | template 68 | HWY_NOINLINE void PrintArray(const T* value, size_t count) { 69 | detail::PrintArray(hwy::detail::MakeTypeInfo(), "", value, count, 0, 70 | count); 71 | } 72 | 73 | } // namespace hwy 74 | 75 | #endif // HWY_PRINT_H_ 76 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/basic_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_BASIC_TYPES_H_ 12 | #define INCLUDE_LIBYUV_BASIC_TYPES_H_ 13 | 14 | #include // For size_t and NULL 15 | 16 | #if !defined(INT_TYPES_DEFINED) && !defined(GG_LONGLONG) 17 | #define INT_TYPES_DEFINED 18 | 19 | #if defined(_MSC_VER) && (_MSC_VER < 1600) 20 | #include // for uintptr_t on x86 21 | typedef unsigned __int64 uint64_t; 22 | typedef __int64 int64_t; 23 | typedef unsigned int uint32_t; 24 | typedef int int32_t; 25 | typedef unsigned short uint16_t; 26 | typedef short int16_t; 27 | typedef unsigned char uint8_t; 28 | typedef signed char int8_t; 29 | #else 30 | #include // for uintptr_t and C99 types 31 | #endif // defined(_MSC_VER) && (_MSC_VER < 1600) 32 | // Types are deprecated. Enable this macro for legacy types. 33 | #ifdef LIBYUV_LEGACY_TYPES 34 | typedef uint64_t uint64; 35 | typedef int64_t int64; 36 | typedef uint32_t uint32; 37 | typedef int32_t int32; 38 | typedef uint16_t uint16; 39 | typedef int16_t int16; 40 | typedef uint8_t uint8; 41 | typedef int8_t int8; 42 | #endif // LIBYUV_LEGACY_TYPES 43 | #endif // INT_TYPES_DEFINED 44 | 45 | #if !defined(LIBYUV_API) 46 | #if defined(_WIN32) || defined(__CYGWIN__) 47 | #if defined(LIBYUV_BUILDING_SHARED_LIBRARY) 48 | #define LIBYUV_API __declspec(dllexport) 49 | #elif defined(LIBYUV_USING_SHARED_LIBRARY) 50 | #define LIBYUV_API __declspec(dllimport) 51 | #else 52 | #define LIBYUV_API 53 | #endif // LIBYUV_BUILDING_SHARED_LIBRARY 54 | #elif defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__APPLE__) && \ 55 | (defined(LIBYUV_BUILDING_SHARED_LIBRARY) || \ 56 | defined(LIBYUV_USING_SHARED_LIBRARY)) 57 | #define LIBYUV_API __attribute__((visibility("default"))) 58 | #else 59 | #define LIBYUV_API 60 | #endif // __GNUC__ 61 | #endif // LIBYUV_API 62 | 63 | // TODO(fbarchard): Remove bool macros. 64 | #define LIBYUV_BOOL int 65 | #define LIBYUV_FALSE 0 66 | #define LIBYUV_TRUE 1 67 | 68 | #endif // INCLUDE_LIBYUV_BASIC_TYPES_H_ 69 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/XScaler.h: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 29/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #ifndef JXLCODER_XSCALER_H 30 | #define JXLCODER_XSCALER_H 31 | 32 | #include 33 | 34 | enum XSampler { 35 | bilinear = 1, 36 | nearest = 2, 37 | cubic = 3, 38 | mitchell = 4, 39 | lanczos = 5, 40 | catmullRom = 6, 41 | hermite = 7, 42 | bSpline = 8, 43 | hann = 9 44 | }; 45 | 46 | namespace coder { 47 | void scaleImageFloat16(const uint16_t* input, 48 | int srcStride, 49 | int inputWidth, int inputHeight, 50 | uint16_t* output, 51 | int dstStride, 52 | int outputWidth, int outputHeight, 53 | int components, 54 | XSampler option); 55 | 56 | void scaleImageU8(const uint8_t *input, 57 | int srcStride, 58 | int inputWidth, int inputHeight, 59 | uint8_t *output, 60 | int dstStride, 61 | int outputWidth, int outputHeight, 62 | int components, 63 | int depth, 64 | XSampler option); 65 | } 66 | 67 | #endif //JXLCODER_XSCALER_H 68 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/scale_argb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_ARGB_H_ 12 | #define INCLUDE_LIBYUV_SCALE_ARGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/scale.h" // For FilterMode 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | LIBYUV_API 23 | int ARGBScale(const uint8_t* src_argb, 24 | int src_stride_argb, 25 | int src_width, 26 | int src_height, 27 | uint8_t* dst_argb, 28 | int dst_stride_argb, 29 | int dst_width, 30 | int dst_height, 31 | enum FilterMode filtering); 32 | 33 | // Clipped scale takes destination rectangle coordinates for clip values. 34 | LIBYUV_API 35 | int ARGBScaleClip(const uint8_t* src_argb, 36 | int src_stride_argb, 37 | int src_width, 38 | int src_height, 39 | uint8_t* dst_argb, 40 | int dst_stride_argb, 41 | int dst_width, 42 | int dst_height, 43 | int clip_x, 44 | int clip_y, 45 | int clip_width, 46 | int clip_height, 47 | enum FilterMode filtering); 48 | 49 | // Scale with YUV conversion to ARGB and clipping. 50 | LIBYUV_API 51 | int YUVToARGBScaleClip(const uint8_t* src_y, 52 | int src_stride_y, 53 | const uint8_t* src_u, 54 | int src_stride_u, 55 | const uint8_t* src_v, 56 | int src_stride_v, 57 | uint32_t src_fourcc, 58 | int src_width, 59 | int src_height, 60 | uint8_t* dst_argb, 61 | int dst_stride_argb, 62 | uint32_t dst_fourcc, 63 | int dst_width, 64 | int dst_height, 65 | int clip_x, 66 | int clip_y, 67 | int clip_width, 68 | int clip_height, 69 | enum FilterMode filtering); 70 | 71 | #ifdef __cplusplus 72 | } // extern "C" 73 | } // namespace libyuv 74 | #endif 75 | 76 | #endif // INCLUDE_LIBYUV_SCALE_ARGB_H_ 77 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /deps.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright (c) the JPEG XL Project Authors. All rights reserved. 3 | # 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | # This file downloads the dependencies needed to build JPEG XL into third_party. 8 | # These dependencies are normally pulled by gtest. 9 | 10 | set -eu 11 | 12 | MYDIR=./ 13 | 14 | # Git revisions we use for the given submodules. Update these whenever you 15 | # update a git submodule. 16 | THIRD_PARTY_BROTLI="36533a866ed1ca4b75cf049f4521e4ec5fe24727" 17 | THIRD_PARTY_HIGHWAY="591ad359a5aa6c320951ebd35f839604c87abe6c" 18 | THIRD_PARTY_SKCMS="b25b07b4b07990811de121c0356155b2ba0f4318" 19 | THIRD_PARTY_SJPEG="e5ab13008bb214deb66d5f3e17ca2f8dbff150bf" 20 | THIRD_PARTY_ZLIB="cacf7f1d4e3d44d871b605da3b647f07d718623f" 21 | THIRD_PARTY_LIBPNG="a40189cf881e9f0db80511c382292a5604c3c3d1" 22 | THIRD_PARTY_LIBJPEG_TURBO="8ecba3647edb6dd940463fedf38ca33a8e2a73d1" # 2.1.5.1 23 | 24 | # Download the target revision from GitHub. 25 | download_github() { 26 | local path="$1" 27 | local project="$2" 28 | 29 | local varname=`echo "$path" | tr '[:lower:]' '[:upper:]'` 30 | varname="${varname//[\/-]/_}" 31 | local sha 32 | eval "sha=\${${varname}}" 33 | 34 | local down_dir="${MYDIR}/downloads" 35 | local local_fn="${down_dir}/${sha}.tar.gz" 36 | if [[ -e "${local_fn}" && -d "${MYDIR}/${path}" ]]; then 37 | echo "${path} already up to date." >&2 38 | return 0 39 | fi 40 | 41 | local url 42 | local strip_components=0 43 | if [[ "${project:0:4}" == "http" ]]; then 44 | # "project" is a googlesource.com base url. 45 | url="${project}${sha}.tar.gz" 46 | else 47 | # GitHub files have a top-level directory 48 | strip_components=1 49 | url="https://github.com/${project}/tarball/${sha}" 50 | fi 51 | 52 | echo "Downloading ${path} version ${sha}..." >&2 53 | mkdir -p "${down_dir}" 54 | curl -L --show-error -o "${local_fn}.tmp" "${url}" 55 | mkdir -p "${MYDIR}/${path}" 56 | tar -zxf "${local_fn}.tmp" -C "${MYDIR}/${path}" \ 57 | --strip-components="${strip_components}" 58 | mv "${local_fn}.tmp" "${local_fn}" 59 | } 60 | 61 | is_git_repository() { 62 | local dir="$1" 63 | local toplevel=$(git rev-parse --show-toplevel) 64 | 65 | [[ "${dir}" == "${toplevel}" ]] 66 | } 67 | 68 | 69 | main() { 70 | if is_git_repository "${MYDIR}"; then 71 | cat >&2 < 25 | using VFromD = int; 26 | #endif 27 | 28 | // On SVE, Vec2..4 are aliases to built-in types. 29 | template 30 | struct Vec2 { 31 | VFromD v0; 32 | VFromD v1; 33 | }; 34 | 35 | template 36 | struct Vec3 { 37 | VFromD v0; 38 | VFromD v1; 39 | VFromD v2; 40 | }; 41 | 42 | template 43 | struct Vec4 { 44 | VFromD v0; 45 | VFromD v1; 46 | VFromD v2; 47 | VFromD v3; 48 | }; 49 | 50 | // D arg is unused but allows deducing D. 51 | template 52 | HWY_API Vec2 Create2(D /* tag */, VFromD v0, VFromD v1) { 53 | return Vec2{v0, v1}; 54 | } 55 | 56 | template 57 | HWY_API Vec3 Create3(D /* tag */, VFromD v0, VFromD v1, VFromD v2) { 58 | return Vec3{v0, v1, v2}; 59 | } 60 | 61 | template 62 | HWY_API Vec4 Create4(D /* tag */, VFromD v0, VFromD v1, VFromD v2, 63 | VFromD v3) { 64 | return Vec4{v0, v1, v2, v3}; 65 | } 66 | 67 | template 68 | HWY_API VFromD Get2(Vec2 tuple) { 69 | static_assert(kIndex < 2, "Tuple index out of bounds"); 70 | return kIndex == 0 ? tuple.v0 : tuple.v1; 71 | } 72 | 73 | template 74 | HWY_API VFromD Get3(Vec3 tuple) { 75 | static_assert(kIndex < 3, "Tuple index out of bounds"); 76 | return kIndex == 0 ? tuple.v0 : kIndex == 1 ? tuple.v1 : tuple.v2; 77 | } 78 | 79 | template 80 | HWY_API VFromD Get4(Vec4 tuple) { 81 | static_assert(kIndex < 4, "Tuple index out of bounds"); 82 | return kIndex == 0 ? tuple.v0 83 | : kIndex == 1 ? tuple.v1 84 | : kIndex == 2 ? tuple.v2 85 | : tuple.v3; 86 | } 87 | 88 | template 89 | HWY_API Vec2 Set2(Vec2 tuple, VFromD val) { 90 | static_assert(kIndex < 2, "Tuple index out of bounds"); 91 | if (kIndex == 0) { 92 | tuple.v0 = val; 93 | } else { 94 | tuple.v1 = val; 95 | } 96 | return tuple; 97 | } 98 | 99 | template 100 | HWY_API Vec3 Set3(Vec3 tuple, VFromD val) { 101 | static_assert(kIndex < 3, "Tuple index out of bounds"); 102 | if (kIndex == 0) { 103 | tuple.v0 = val; 104 | } else if (kIndex == 1) { 105 | tuple.v1 = val; 106 | } else { 107 | tuple.v2 = val; 108 | } 109 | return tuple; 110 | } 111 | 112 | template 113 | HWY_API Vec4 Set4(Vec4 tuple, VFromD val) { 114 | static_assert(kIndex < 4, "Tuple index out of bounds"); 115 | if (kIndex == 0) { 116 | tuple.v0 = val; 117 | } else if (kIndex == 1) { 118 | tuple.v1 = val; 119 | } else if (kIndex == 2) { 120 | tuple.v2 = val; 121 | } else { 122 | tuple.v3 = val; 123 | } 124 | return tuple; 125 | } -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/cache_control.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_CACHE_CONTROL_H_ 17 | #define HIGHWAY_HWY_CACHE_CONTROL_H_ 18 | 19 | #include "hwy/base.h" 20 | 21 | // Requires SSE2; fails to compile on 32-bit Clang 7 (see 22 | // https://github.com/gperftools/gperftools/issues/946). 23 | #if !defined(__SSE2__) || (HWY_COMPILER_CLANG && HWY_ARCH_X86_32) 24 | #undef HWY_DISABLE_CACHE_CONTROL 25 | #define HWY_DISABLE_CACHE_CONTROL 26 | #endif 27 | 28 | // intrin.h is sufficient on MSVC and already included by base.h. 29 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) && !HWY_COMPILER_MSVC 30 | #include // SSE2 31 | #include // _mm_prefetch 32 | #endif 33 | 34 | namespace hwy { 35 | 36 | // Even if N*sizeof(T) is smaller, Stream may write a multiple of this size. 37 | #define HWY_STREAM_MULTIPLE 16 38 | 39 | // The following functions may also require an attribute. 40 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) && !HWY_COMPILER_MSVC 41 | #define HWY_ATTR_CACHE __attribute__((target("sse2"))) 42 | #else 43 | #define HWY_ATTR_CACHE 44 | #endif 45 | 46 | // Windows.h #defines this, which causes infinite recursion. Temporarily 47 | // undefine to avoid conflict with our function. 48 | // TODO(janwas): remove when this function is removed. 49 | #pragma push_macro("LoadFence") 50 | #undef LoadFence 51 | 52 | // Delays subsequent loads until prior loads are visible. Beware of potentially 53 | // differing behavior across architectures and vendors: on Intel but not 54 | // AMD CPUs, also serves as a full fence (waits for all prior instructions to 55 | // complete). 56 | HWY_INLINE HWY_ATTR_CACHE void LoadFence() { 57 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) 58 | _mm_lfence(); 59 | #endif 60 | } 61 | 62 | // TODO(janwas): remove when this function is removed. (See above.) 63 | #pragma pop_macro("LoadFence") 64 | 65 | // Ensures values written by previous `Stream` calls are visible on the current 66 | // core. This is NOT sufficient for synchronizing across cores; when `Stream` 67 | // outputs are to be consumed by other core(s), the producer must publish 68 | // availability (e.g. via mutex or atomic_flag) after `FlushStream`. 69 | HWY_INLINE HWY_ATTR_CACHE void FlushStream() { 70 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) 71 | _mm_sfence(); 72 | #endif 73 | } 74 | 75 | // Optionally begins loading the cache line containing "p" to reduce latency of 76 | // subsequent actual loads. 77 | template 78 | HWY_INLINE HWY_ATTR_CACHE void Prefetch(const T* p) { 79 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) 80 | _mm_prefetch(reinterpret_cast(p), _MM_HINT_T0); 81 | #elif HWY_COMPILER_GCC // includes clang 82 | // Hint=0 (NTA) behavior differs, but skipping outer caches is probably not 83 | // desirable, so use the default 3 (keep in caches). 84 | __builtin_prefetch(p, /*write=*/0, /*hint=*/3); 85 | #else 86 | (void)p; 87 | #endif 88 | } 89 | 90 | // Invalidates and flushes the cache line containing "p", if possible. 91 | HWY_INLINE HWY_ATTR_CACHE void FlushCacheline(const void* p) { 92 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) 93 | _mm_clflush(p); 94 | #else 95 | (void)p; 96 | #endif 97 | } 98 | 99 | // When called inside a spin-loop, may reduce power consumption. 100 | HWY_INLINE HWY_ATTR_CACHE void Pause() { 101 | #if HWY_ARCH_X86 && !defined(HWY_DISABLE_CACHE_CONTROL) 102 | _mm_pause(); 103 | #endif 104 | } 105 | 106 | } // namespace hwy 107 | 108 | #endif // HIGHWAY_HWY_CACHE_CONTROL_H_ 109 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/cpu_id.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_CPU_ID_H_ 12 | #define INCLUDE_LIBYUV_CPU_ID_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | // Internal flag to indicate cpuid requires initialization. 22 | static const int kCpuInitialized = 0x1; 23 | 24 | // These flags are only valid on ARM processors. 25 | static const int kCpuHasARM = 0x2; 26 | static const int kCpuHasNEON = 0x4; 27 | // 0x8 reserved for future ARM flag. 28 | 29 | // These flags are only valid on x86 processors. 30 | static const int kCpuHasX86 = 0x10; 31 | static const int kCpuHasSSE2 = 0x20; 32 | static const int kCpuHasSSSE3 = 0x40; 33 | static const int kCpuHasSSE41 = 0x80; 34 | static const int kCpuHasSSE42 = 0x100; // unused at this time. 35 | static const int kCpuHasAVX = 0x200; 36 | static const int kCpuHasAVX2 = 0x400; 37 | static const int kCpuHasERMS = 0x800; 38 | static const int kCpuHasFMA3 = 0x1000; 39 | static const int kCpuHasF16C = 0x2000; 40 | static const int kCpuHasGFNI = 0x4000; 41 | static const int kCpuHasAVX512BW = 0x8000; 42 | static const int kCpuHasAVX512VL = 0x10000; 43 | static const int kCpuHasAVX512VNNI = 0x20000; 44 | static const int kCpuHasAVX512VBMI = 0x40000; 45 | static const int kCpuHasAVX512VBMI2 = 0x80000; 46 | static const int kCpuHasAVX512VBITALG = 0x100000; 47 | static const int kCpuHasAVX512VPOPCNTDQ = 0x200000; 48 | 49 | // These flags are only valid on MIPS processors. 50 | static const int kCpuHasMIPS = 0x400000; 51 | static const int kCpuHasMSA = 0x800000; 52 | 53 | // These flags are only valid on LOONGARCH processors. 54 | static const int kCpuHasLOONGARCH = 0x2000000; 55 | static const int kCpuHasLSX = 0x4000000; 56 | static const int kCpuHasLASX = 0x8000000; 57 | 58 | // Optional init function. TestCpuFlag does an auto-init. 59 | // Returns cpu_info flags. 60 | LIBYUV_API 61 | int InitCpuFlags(void); 62 | 63 | // Detect CPU has SSE2 etc. 64 | // Test_flag parameter should be one of kCpuHas constants above. 65 | // Returns non-zero if instruction set is detected 66 | static __inline int TestCpuFlag(int test_flag) { 67 | LIBYUV_API extern int cpu_info_; 68 | #ifdef __ATOMIC_RELAXED 69 | int cpu_info = __atomic_load_n(&cpu_info_, __ATOMIC_RELAXED); 70 | #else 71 | int cpu_info = cpu_info_; 72 | #endif 73 | return (!cpu_info ? InitCpuFlags() : cpu_info) & test_flag; 74 | } 75 | 76 | // Internal function for parsing /proc/cpuinfo. 77 | LIBYUV_API 78 | int ArmCpuCaps(const char* cpuinfo_name); 79 | LIBYUV_API 80 | int MipsCpuCaps(const char* cpuinfo_name); 81 | 82 | // For testing, allow CPU flags to be disabled. 83 | // ie MaskCpuFlags(~kCpuHasSSSE3) to disable SSSE3. 84 | // MaskCpuFlags(-1) to enable all cpu specific optimizations. 85 | // MaskCpuFlags(1) to disable all cpu specific optimizations. 86 | // MaskCpuFlags(0) to reset state so next call will auto init. 87 | // Returns cpu_info flags. 88 | LIBYUV_API 89 | int MaskCpuFlags(int enable_flags); 90 | 91 | // Sets the CPU flags to |cpu_flags|, bypassing the detection code. |cpu_flags| 92 | // should be a valid combination of the kCpuHas constants above and include 93 | // kCpuInitialized. Use this method when running in a sandboxed process where 94 | // the detection code might fail (as it might access /proc/cpuinfo). In such 95 | // cases the cpu_info can be obtained from a non sandboxed process by calling 96 | // InitCpuFlags() and passed to the sandboxed process (via command line 97 | // parameters, IPC...) which can then call this method to initialize the CPU 98 | // flags. 99 | // Notes: 100 | // - when specifying 0 for |cpu_flags|, the auto initialization is enabled 101 | // again. 102 | // - enabling CPU features that are not supported by the CPU will result in 103 | // undefined behavior. 104 | // TODO(fbarchard): consider writing a helper function that translates from 105 | // other library CPU info to libyuv CPU info and add a .md doc that explains 106 | // CPU detection. 107 | static __inline void SetCpuFlags(int cpu_flags) { 108 | LIBYUV_API extern int cpu_info_; 109 | #ifdef __ATOMIC_RELAXED 110 | __atomic_store_n(&cpu_info_, cpu_flags, __ATOMIC_RELAXED); 111 | #else 112 | cpu_info_ = cpu_flags; 113 | #endif 114 | } 115 | 116 | // Low level cpuid for X86. Returns zeros on other CPUs. 117 | // eax is the info type that you want. 118 | // ecx is typically the cpu number, and should normally be zero. 119 | LIBYUV_API 120 | void CpuId(int info_eax, int info_ecx, int* cpu_info); 121 | 122 | #ifdef __cplusplus 123 | } // extern "C" 124 | } // namespace libyuv 125 | #endif 126 | 127 | #endif // INCLUDE_LIBYUV_CPU_ID_H_ 128 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/compare_row.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_COMPARE_ROW_H_ 12 | #define INCLUDE_LIBYUV_COMPARE_ROW_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | #if defined(__pnacl__) || defined(__CLR_VER) || \ 22 | (defined(__native_client__) && defined(__x86_64__)) || \ 23 | (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 24 | #define LIBYUV_DISABLE_X86 25 | #endif 26 | #if defined(__native_client__) 27 | #define LIBYUV_DISABLE_NEON 28 | #endif 29 | // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 30 | #if defined(__has_feature) 31 | #if __has_feature(memory_sanitizer) 32 | #define LIBYUV_DISABLE_X86 33 | #endif 34 | #endif 35 | // Visual C 2012 required for AVX2. 36 | #if defined(_M_IX86) && !defined(__clang__) && defined(_MSC_VER) && \ 37 | _MSC_VER >= 1700 38 | #define VISUALC_HAS_AVX2 1 39 | #endif // VisualStudio >= 2012 40 | 41 | // clang >= 3.4.0 required for AVX2. 42 | #if defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) 43 | #if (__clang_major__ > 3) || (__clang_major__ == 3 && (__clang_minor__ >= 4)) 44 | #define CLANG_HAS_AVX2 1 45 | #endif // clang >= 3.4 46 | #endif // __clang__ 47 | 48 | // The following are available for Visual C and GCC: 49 | #if !defined(LIBYUV_DISABLE_X86) && \ 50 | (defined(__x86_64__) || defined(__i386__) || defined(_M_IX86)) 51 | #define HAS_HASHDJB2_SSE41 52 | #define HAS_SUMSQUAREERROR_SSE2 53 | #define HAS_HAMMINGDISTANCE_SSE42 54 | #endif 55 | 56 | // The following are available for Visual C and clangcl 32 bit: 57 | #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) && \ 58 | !defined(__clang__) && \ 59 | (defined(VISUALC_HAS_AVX2) || defined(CLANG_HAS_AVX2)) 60 | #define HAS_HASHDJB2_AVX2 61 | #define HAS_SUMSQUAREERROR_AVX2 62 | #endif 63 | 64 | // The following are available for GCC and clangcl: 65 | #if !defined(LIBYUV_DISABLE_X86) && (defined(__x86_64__) || defined(__i386__)) 66 | #define HAS_HAMMINGDISTANCE_SSSE3 67 | #endif 68 | 69 | // The following are available for GCC and clangcl: 70 | #if !defined(LIBYUV_DISABLE_X86) && defined(CLANG_HAS_AVX2) && \ 71 | (defined(__x86_64__) || defined(__i386__)) 72 | #define HAS_HAMMINGDISTANCE_AVX2 73 | #endif 74 | 75 | // The following are available for Neon: 76 | #if !defined(LIBYUV_DISABLE_NEON) && \ 77 | (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) 78 | #define HAS_SUMSQUAREERROR_NEON 79 | #define HAS_HAMMINGDISTANCE_NEON 80 | #endif 81 | 82 | #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) 83 | #define HAS_HAMMINGDISTANCE_MSA 84 | #define HAS_SUMSQUAREERROR_MSA 85 | #endif 86 | 87 | uint32_t HammingDistance_C(const uint8_t* src_a, 88 | const uint8_t* src_b, 89 | int count); 90 | uint32_t HammingDistance_SSE42(const uint8_t* src_a, 91 | const uint8_t* src_b, 92 | int count); 93 | uint32_t HammingDistance_SSSE3(const uint8_t* src_a, 94 | const uint8_t* src_b, 95 | int count); 96 | uint32_t HammingDistance_AVX2(const uint8_t* src_a, 97 | const uint8_t* src_b, 98 | int count); 99 | uint32_t HammingDistance_NEON(const uint8_t* src_a, 100 | const uint8_t* src_b, 101 | int count); 102 | uint32_t HammingDistance_MSA(const uint8_t* src_a, 103 | const uint8_t* src_b, 104 | int count); 105 | uint32_t SumSquareError_C(const uint8_t* src_a, 106 | const uint8_t* src_b, 107 | int count); 108 | uint32_t SumSquareError_SSE2(const uint8_t* src_a, 109 | const uint8_t* src_b, 110 | int count); 111 | uint32_t SumSquareError_AVX2(const uint8_t* src_a, 112 | const uint8_t* src_b, 113 | int count); 114 | uint32_t SumSquareError_NEON(const uint8_t* src_a, 115 | const uint8_t* src_b, 116 | int count); 117 | uint32_t SumSquareError_MSA(const uint8_t* src_a, 118 | const uint8_t* src_b, 119 | int count); 120 | 121 | uint32_t HashDjb2_C(const uint8_t* src, int count, uint32_t seed); 122 | uint32_t HashDjb2_SSE41(const uint8_t* src, int count, uint32_t seed); 123 | uint32_t HashDjb2_AVX2(const uint8_t* src, int count, uint32_t seed); 124 | 125 | #ifdef __cplusplus 126 | } // extern "C" 127 | } // namespace libyuv 128 | #endif 129 | 130 | #endif // INCLUDE_LIBYUV_COMPARE_ROW_H_ 131 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/robust_statistics.h: -------------------------------------------------------------------------------- 1 | // Copyright 2023 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_ROBUST_STATISTICS_H_ 17 | #define HIGHWAY_HWY_ROBUST_STATISTICS_H_ 18 | 19 | #include // std::sort, std::find_if 20 | #include 21 | #include // std::pair 22 | #include 23 | 24 | #include "hwy/base.h" 25 | 26 | namespace hwy { 27 | namespace robust_statistics { 28 | 29 | // Sorts integral values in ascending order (e.g. for Mode). About 3x faster 30 | // than std::sort for input distributions with very few unique values. 31 | template 32 | void CountingSort(T* values, size_t num_values) { 33 | // Unique values and their frequency (similar to flat_map). 34 | using Unique = std::pair; 35 | std::vector unique; 36 | for (size_t i = 0; i < num_values; ++i) { 37 | const T value = values[i]; 38 | const auto pos = 39 | std::find_if(unique.begin(), unique.end(), 40 | [value](const Unique u) { return u.first == value; }); 41 | if (pos == unique.end()) { 42 | unique.push_back(std::make_pair(value, 1)); 43 | } else { 44 | ++pos->second; 45 | } 46 | } 47 | 48 | // Sort in ascending order of value (pair.first). 49 | std::sort(unique.begin(), unique.end()); 50 | 51 | // Write that many copies of each unique value to the array. 52 | T* HWY_RESTRICT p = values; 53 | for (const auto& value_count : unique) { 54 | std::fill(p, p + value_count.second, value_count.first); 55 | p += value_count.second; 56 | } 57 | HWY_ASSERT(p == values + num_values); 58 | } 59 | 60 | // @return i in [idx_begin, idx_begin + half_count) that minimizes 61 | // sorted[i + half_count] - sorted[i]. 62 | template 63 | size_t MinRange(const T* const HWY_RESTRICT sorted, const size_t idx_begin, 64 | const size_t half_count) { 65 | T min_range = std::numeric_limits::max(); 66 | size_t min_idx = 0; 67 | 68 | for (size_t idx = idx_begin; idx < idx_begin + half_count; ++idx) { 69 | HWY_ASSERT(sorted[idx] <= sorted[idx + half_count]); 70 | const T range = sorted[idx + half_count] - sorted[idx]; 71 | if (range < min_range) { 72 | min_range = range; 73 | min_idx = idx; 74 | } 75 | } 76 | 77 | return min_idx; 78 | } 79 | 80 | // Returns an estimate of the mode by calling MinRange on successively 81 | // halved intervals. "sorted" must be in ascending order. This is the 82 | // Half Sample Mode estimator proposed by Bickel in "On a fast, robust 83 | // estimator of the mode", with complexity O(N log N). The mode is less 84 | // affected by outliers in highly-skewed distributions than the median. 85 | // The averaging operation below assumes "T" is an unsigned integer type. 86 | template 87 | T ModeOfSorted(const T* const HWY_RESTRICT sorted, const size_t num_values) { 88 | size_t idx_begin = 0; 89 | size_t half_count = num_values / 2; 90 | while (half_count > 1) { 91 | idx_begin = MinRange(sorted, idx_begin, half_count); 92 | half_count >>= 1; 93 | } 94 | 95 | const T x = sorted[idx_begin + 0]; 96 | if (half_count == 0) { 97 | return x; 98 | } 99 | HWY_ASSERT(half_count == 1); 100 | const T average = (x + sorted[idx_begin + 1] + 1) / 2; 101 | return average; 102 | } 103 | 104 | // Returns the mode. Side effect: sorts "values". 105 | template 106 | T Mode(T* values, const size_t num_values) { 107 | CountingSort(values, num_values); 108 | return ModeOfSorted(values, num_values); 109 | } 110 | 111 | template 112 | T Mode(T (&values)[N]) { 113 | return Mode(&values[0], N); 114 | } 115 | 116 | // Returns the median value. Side effect: sorts "values". 117 | template 118 | T Median(T* values, const size_t num_values) { 119 | HWY_ASSERT(num_values != 0); 120 | std::sort(values, values + num_values); 121 | const size_t half = num_values / 2; 122 | // Odd count: return middle 123 | if (num_values % 2) { 124 | return values[half]; 125 | } 126 | // Even count: return average of middle two. 127 | return (values[half] + values[half - 1] + 1) / 2; 128 | } 129 | 130 | // Returns a robust measure of variability. 131 | template 132 | T MedianAbsoluteDeviation(const T* values, const size_t num_values, 133 | const T median) { 134 | HWY_ASSERT(num_values != 0); 135 | std::vector abs_deviations; 136 | abs_deviations.reserve(num_values); 137 | for (size_t i = 0; i < num_values; ++i) { 138 | const int64_t abs = std::abs(static_cast(values[i]) - 139 | static_cast(median)); 140 | abs_deviations.push_back(static_cast(abs)); 141 | } 142 | return Median(abs_deviations.data(), num_values); 143 | } 144 | 145 | } // namespace robust_statistics 146 | } // namespace hwy 147 | 148 | #endif // HIGHWAY_HWY_ROBUST_STATISTICS_H_ 149 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/mjpeg_decoder.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_MJPEG_DECODER_H_ 12 | #define INCLUDE_LIBYUV_MJPEG_DECODER_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | // NOTE: For a simplified public API use convert.h MJPGToI420(). 18 | 19 | struct jpeg_common_struct; 20 | struct jpeg_decompress_struct; 21 | struct jpeg_source_mgr; 22 | 23 | namespace libyuv { 24 | 25 | #ifdef __cplusplus 26 | extern "C" { 27 | #endif 28 | 29 | LIBYUV_BOOL ValidateJpeg(const uint8_t* sample, size_t sample_size); 30 | 31 | #ifdef __cplusplus 32 | } // extern "C" 33 | #endif 34 | 35 | static const uint32_t kUnknownDataSize = 0xFFFFFFFF; 36 | 37 | enum JpegSubsamplingType { 38 | kJpegYuv420, 39 | kJpegYuv422, 40 | kJpegYuv444, 41 | kJpegYuv400, 42 | kJpegUnknown 43 | }; 44 | 45 | struct Buffer { 46 | const uint8_t* data; 47 | int len; 48 | }; 49 | 50 | struct BufferVector { 51 | Buffer* buffers; 52 | int len; 53 | int pos; 54 | }; 55 | 56 | struct SetJmpErrorMgr; 57 | 58 | // MJPEG ("Motion JPEG") is a pseudo-standard video codec where the frames are 59 | // simply independent JPEG images with a fixed huffman table (which is omitted). 60 | // It is rarely used in video transmission, but is common as a camera capture 61 | // format, especially in Logitech devices. This class implements a decoder for 62 | // MJPEG frames. 63 | // 64 | // See http://tools.ietf.org/html/rfc2435 65 | class LIBYUV_API MJpegDecoder { 66 | public: 67 | typedef void (*CallbackFunction)(void* opaque, 68 | const uint8_t* const* data, 69 | const int* strides, 70 | int rows); 71 | 72 | static const int kColorSpaceUnknown; 73 | static const int kColorSpaceGrayscale; 74 | static const int kColorSpaceRgb; 75 | static const int kColorSpaceYCbCr; 76 | static const int kColorSpaceCMYK; 77 | static const int kColorSpaceYCCK; 78 | 79 | MJpegDecoder(); 80 | ~MJpegDecoder(); 81 | 82 | // Loads a new frame, reads its headers, and determines the uncompressed 83 | // image format. 84 | // Returns LIBYUV_TRUE if image looks valid and format is supported. 85 | // If return value is LIBYUV_TRUE, then the values for all the following 86 | // getters are populated. 87 | // src_len is the size of the compressed mjpeg frame in bytes. 88 | LIBYUV_BOOL LoadFrame(const uint8_t* src, size_t src_len); 89 | 90 | // Returns width of the last loaded frame in pixels. 91 | int GetWidth(); 92 | 93 | // Returns height of the last loaded frame in pixels. 94 | int GetHeight(); 95 | 96 | // Returns format of the last loaded frame. The return value is one of the 97 | // kColorSpace* constants. 98 | int GetColorSpace(); 99 | 100 | // Number of color components in the color space. 101 | int GetNumComponents(); 102 | 103 | // Sample factors of the n-th component. 104 | int GetHorizSampFactor(int component); 105 | 106 | int GetVertSampFactor(int component); 107 | 108 | int GetHorizSubSampFactor(int component); 109 | 110 | int GetVertSubSampFactor(int component); 111 | 112 | // Public for testability. 113 | int GetImageScanlinesPerImcuRow(); 114 | 115 | // Public for testability. 116 | int GetComponentScanlinesPerImcuRow(int component); 117 | 118 | // Width of a component in bytes. 119 | int GetComponentWidth(int component); 120 | 121 | // Height of a component. 122 | int GetComponentHeight(int component); 123 | 124 | // Width of a component in bytes with padding for DCTSIZE. Public for testing. 125 | int GetComponentStride(int component); 126 | 127 | // Size of a component in bytes. 128 | int GetComponentSize(int component); 129 | 130 | // Call this after LoadFrame() if you decide you don't want to decode it 131 | // after all. 132 | LIBYUV_BOOL UnloadFrame(); 133 | 134 | // Decodes the entire image into a one-buffer-per-color-component format. 135 | // dst_width must match exactly. dst_height must be <= to image height; if 136 | // less, the image is cropped. "planes" must have size equal to at least 137 | // GetNumComponents() and they must point to non-overlapping buffers of size 138 | // at least GetComponentSize(i). The pointers in planes are incremented 139 | // to point to after the end of the written data. 140 | // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded. 141 | LIBYUV_BOOL DecodeToBuffers(uint8_t** planes, int dst_width, int dst_height); 142 | 143 | // Decodes the entire image and passes the data via repeated calls to a 144 | // callback function. Each call will get the data for a whole number of 145 | // image scanlines. 146 | // TODO(fbarchard): Add dst_x, dst_y to allow specific rect to be decoded. 147 | LIBYUV_BOOL DecodeToCallback(CallbackFunction fn, 148 | void* opaque, 149 | int dst_width, 150 | int dst_height); 151 | 152 | // The helper function which recognizes the jpeg sub-sampling type. 153 | static JpegSubsamplingType JpegSubsamplingTypeHelper( 154 | int* subsample_x, 155 | int* subsample_y, 156 | int number_of_components); 157 | 158 | private: 159 | void AllocOutputBuffers(int num_outbufs); 160 | void DestroyOutputBuffers(); 161 | 162 | LIBYUV_BOOL StartDecode(); 163 | LIBYUV_BOOL FinishDecode(); 164 | 165 | void SetScanlinePointers(uint8_t** data); 166 | LIBYUV_BOOL DecodeImcuRow(); 167 | 168 | int GetComponentScanlinePadding(int component); 169 | 170 | // A buffer holding the input data for a frame. 171 | Buffer buf_; 172 | BufferVector buf_vec_; 173 | 174 | jpeg_decompress_struct* decompress_struct_; 175 | jpeg_source_mgr* source_mgr_; 176 | SetJmpErrorMgr* error_mgr_; 177 | 178 | // LIBYUV_TRUE iff at least one component has scanline padding. (i.e., 179 | // GetComponentScanlinePadding() != 0.) 180 | LIBYUV_BOOL has_scanline_padding_; 181 | 182 | // Temporaries used to point to scanline outputs. 183 | int num_outbufs_; // Outermost size of all arrays below. 184 | uint8_t*** scanlines_; 185 | int* scanlines_sizes_; 186 | // Temporary buffer used for decoding when we can't decode directly to the 187 | // output buffers. Large enough for just one iMCU row. 188 | uint8_t** databuf_; 189 | int* databuf_strides_; 190 | }; 191 | 192 | } // namespace libyuv 193 | 194 | #endif // __cplusplus 195 | #endif // INCLUDE_LIBYUV_MJPEG_DECODER_H_ 196 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/convert_from.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_CONVERT_FROM_H_ 12 | #define INCLUDE_LIBYUV_CONVERT_FROM_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | #include "libyuv/rotate.h" 16 | 17 | #ifdef __cplusplus 18 | namespace libyuv { 19 | extern "C" { 20 | #endif 21 | 22 | // See Also convert.h for conversions from formats to I420. 23 | 24 | // Convert 8 bit YUV to 10 bit. 25 | #define H420ToH010 I420ToI010 26 | LIBYUV_API 27 | int I420ToI010(const uint8_t* src_y, 28 | int src_stride_y, 29 | const uint8_t* src_u, 30 | int src_stride_u, 31 | const uint8_t* src_v, 32 | int src_stride_v, 33 | uint16_t* dst_y, 34 | int dst_stride_y, 35 | uint16_t* dst_u, 36 | int dst_stride_u, 37 | uint16_t* dst_v, 38 | int dst_stride_v, 39 | int width, 40 | int height); 41 | 42 | // Convert 8 bit YUV to 12 bit. 43 | #define H420ToH012 I420ToI012 44 | LIBYUV_API 45 | int I420ToI012(const uint8_t* src_y, 46 | int src_stride_y, 47 | const uint8_t* src_u, 48 | int src_stride_u, 49 | const uint8_t* src_v, 50 | int src_stride_v, 51 | uint16_t* dst_y, 52 | int dst_stride_y, 53 | uint16_t* dst_u, 54 | int dst_stride_u, 55 | uint16_t* dst_v, 56 | int dst_stride_v, 57 | int width, 58 | int height); 59 | 60 | LIBYUV_API 61 | int I420ToI422(const uint8_t* src_y, 62 | int src_stride_y, 63 | const uint8_t* src_u, 64 | int src_stride_u, 65 | const uint8_t* src_v, 66 | int src_stride_v, 67 | uint8_t* dst_y, 68 | int dst_stride_y, 69 | uint8_t* dst_u, 70 | int dst_stride_u, 71 | uint8_t* dst_v, 72 | int dst_stride_v, 73 | int width, 74 | int height); 75 | 76 | LIBYUV_API 77 | int I420ToI444(const uint8_t* src_y, 78 | int src_stride_y, 79 | const uint8_t* src_u, 80 | int src_stride_u, 81 | const uint8_t* src_v, 82 | int src_stride_v, 83 | uint8_t* dst_y, 84 | int dst_stride_y, 85 | uint8_t* dst_u, 86 | int dst_stride_u, 87 | uint8_t* dst_v, 88 | int dst_stride_v, 89 | int width, 90 | int height); 91 | 92 | // Copy to I400. Source can be I420, I422, I444, I400, NV12 or NV21. 93 | LIBYUV_API 94 | int I400Copy(const uint8_t* src_y, 95 | int src_stride_y, 96 | uint8_t* dst_y, 97 | int dst_stride_y, 98 | int width, 99 | int height); 100 | 101 | LIBYUV_API 102 | int I420ToNV12(const uint8_t* src_y, 103 | int src_stride_y, 104 | const uint8_t* src_u, 105 | int src_stride_u, 106 | const uint8_t* src_v, 107 | int src_stride_v, 108 | uint8_t* dst_y, 109 | int dst_stride_y, 110 | uint8_t* dst_uv, 111 | int dst_stride_uv, 112 | int width, 113 | int height); 114 | 115 | LIBYUV_API 116 | int I420ToNV21(const uint8_t* src_y, 117 | int src_stride_y, 118 | const uint8_t* src_u, 119 | int src_stride_u, 120 | const uint8_t* src_v, 121 | int src_stride_v, 122 | uint8_t* dst_y, 123 | int dst_stride_y, 124 | uint8_t* dst_vu, 125 | int dst_stride_vu, 126 | int width, 127 | int height); 128 | 129 | LIBYUV_API 130 | int I420ToYUY2(const uint8_t* src_y, 131 | int src_stride_y, 132 | const uint8_t* src_u, 133 | int src_stride_u, 134 | const uint8_t* src_v, 135 | int src_stride_v, 136 | uint8_t* dst_yuy2, 137 | int dst_stride_yuy2, 138 | int width, 139 | int height); 140 | 141 | LIBYUV_API 142 | int I420ToUYVY(const uint8_t* src_y, 143 | int src_stride_y, 144 | const uint8_t* src_u, 145 | int src_stride_u, 146 | const uint8_t* src_v, 147 | int src_stride_v, 148 | uint8_t* dst_uyvy, 149 | int dst_stride_uyvy, 150 | int width, 151 | int height); 152 | 153 | // The following are from convert_argb.h 154 | // DEPRECATED: The prototypes will be removed in future. Use convert_argb.h 155 | 156 | // Convert I420 to ARGB. 157 | LIBYUV_API 158 | int I420ToARGB(const uint8_t* src_y, 159 | int src_stride_y, 160 | const uint8_t* src_u, 161 | int src_stride_u, 162 | const uint8_t* src_v, 163 | int src_stride_v, 164 | uint8_t* dst_argb, 165 | int dst_stride_argb, 166 | int width, 167 | int height); 168 | 169 | // Convert I420 to ABGR. 170 | LIBYUV_API 171 | int I420ToABGR(const uint8_t* src_y, 172 | int src_stride_y, 173 | const uint8_t* src_u, 174 | int src_stride_u, 175 | const uint8_t* src_v, 176 | int src_stride_v, 177 | uint8_t* dst_abgr, 178 | int dst_stride_abgr, 179 | int width, 180 | int height); 181 | 182 | // Convert I420 to specified format. 183 | // "dst_sample_stride" is bytes in a row for the destination. Pass 0 if the 184 | // buffer has contiguous rows. Can be negative. A multiple of 16 is optimal. 185 | LIBYUV_API 186 | int ConvertFromI420(const uint8_t* y, 187 | int y_stride, 188 | const uint8_t* u, 189 | int u_stride, 190 | const uint8_t* v, 191 | int v_stride, 192 | uint8_t* dst_sample, 193 | int dst_sample_stride, 194 | int width, 195 | int height, 196 | uint32_t fourcc); 197 | 198 | #ifdef __cplusplus 199 | } // extern "C" 200 | } // namespace libyuv 201 | #endif 202 | 203 | #endif // INCLUDE_LIBYUV_CONVERT_FROM_H_ 204 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/BitmapScaler.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "JniExceptions.h" 5 | #include "XScaler.h" 6 | #include "Rgb1010102toF16.h" 7 | #include "RGBAlpha.h" 8 | #include "libyuv/convert_argb.h" 9 | #include "libyuv/convert_from_argb.h" 10 | #include "CopyUnaligned.h" 11 | 12 | using namespace std; 13 | 14 | extern "C" 15 | JNIEXPORT jobject JNICALL 16 | Java_com_t8rin_bitmapscaler_BitmapScaler_scaleImpl(JNIEnv *env, jobject thiz, jobject bitmap, 17 | jint dst_width, jint dst_height, 18 | jint scale_mode) { 19 | AndroidBitmapInfo info; 20 | if (AndroidBitmap_getInfo(env, bitmap, &info) < 0) { 21 | throwPixelsException(env); 22 | return static_cast(nullptr); 23 | } 24 | 25 | void *addr = nullptr; 26 | if (AndroidBitmap_lockPixels(env, bitmap, &addr) != 0) { 27 | throwPixelsException(env); 28 | return static_cast(nullptr); 29 | } 30 | 31 | vector rgbaPixels(info.stride * info.height); 32 | memcpy(rgbaPixels.data(), addr, info.stride * info.height); 33 | 34 | if (AndroidBitmap_unlockPixels(env, bitmap) != 0) { 35 | string exc = "Unlocking pixels has failed"; 36 | throwException(env, exc); 37 | return static_cast(nullptr); 38 | } 39 | 40 | int imageStride = (int) info.stride; 41 | 42 | if (info.format == ANDROID_BITMAP_FORMAT_RGBA_1010102) { 43 | imageStride = (int) info.width * 4 * (int) sizeof(uint16_t); 44 | vector halfFloatPixels(imageStride * info.height); 45 | coder::ConvertRGBA1010102toF16(reinterpret_cast(rgbaPixels.data()), 46 | (int) info.stride, 47 | reinterpret_cast(halfFloatPixels.data()), 48 | (int) imageStride, 49 | (int) info.width, 50 | (int) info.height); 51 | rgbaPixels = halfFloatPixels; 52 | } else if (info.format == ANDROID_BITMAP_FORMAT_RGB_565) { 53 | int newStride = (int) info.width * 4 * (int) sizeof(uint8_t); 54 | std::vector rgba8888Pixels(newStride * info.height); 55 | libyuv::RGB565ToARGB(rgbaPixels.data(), (int) info.stride, 56 | rgba8888Pixels.data(), newStride, 57 | (int) info.width, (int) info.height); 58 | libyuv::ARGBToABGR(rgba8888Pixels.data(), newStride, 59 | rgba8888Pixels.data(), newStride, 60 | (int) info.width, (int) info.height); 61 | imageStride = newStride; 62 | rgbaPixels = rgba8888Pixels; 63 | } else if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) { 64 | coder::UnpremultiplyRGBA(rgbaPixels.data(), imageStride, 65 | rgbaPixels.data(), imageStride, 66 | (int) info.width, 67 | (int) info.height); 68 | } 69 | 70 | bool useFloat16 = info.format == ANDROID_BITMAP_FORMAT_RGBA_F16 || 71 | info.format == ANDROID_BITMAP_FORMAT_RGBA_1010102; 72 | 73 | std::vector rgbPixels; 74 | int requiredStride = (int) info.width * 4 * 75 | (int) (useFloat16 ? sizeof(uint16_t) : sizeof(uint8_t)); 76 | 77 | int dstStride = (int) dst_width * 4 * (int) (useFloat16 ? sizeof(uint16_t) : sizeof(uint8_t)); 78 | 79 | if (requiredStride == info.stride) { 80 | rgbPixels = rgbaPixels; 81 | } else { 82 | rgbPixels.resize(requiredStride * (int) info.height); 83 | coder::CopyUnalignedRGBA(rgbaPixels.data(), imageStride, rgbPixels.data(), 84 | requiredStride, (int) info.width, (int) info.height, 85 | (int) (useFloat16 ? sizeof(uint16_t) 86 | : sizeof(uint8_t))); 87 | } 88 | imageStride = requiredStride; 89 | 90 | vector output(dstStride * dst_height); 91 | 92 | 93 | if (useFloat16) { 94 | coder::scaleImageFloat16( 95 | reinterpret_cast(rgbPixels.data()), 96 | imageStride, 97 | info.width, 98 | info.height, 99 | reinterpret_cast(output.data()), 100 | dstStride, 101 | dst_width, 102 | dst_height, 103 | 4, 104 | static_cast(scale_mode) 105 | ); 106 | } else { 107 | coder::scaleImageU8( 108 | rgbPixels.data(), 109 | imageStride, 110 | info.width, 111 | info.height, 112 | output.data(), 113 | dstStride, 114 | dst_width, 115 | dst_height, 116 | 4, 117 | 8, 118 | static_cast(scale_mode) 119 | ); 120 | } 121 | 122 | rgbPixels.clear(); 123 | 124 | std::string bitmapPixelConfig = useFloat16 ? "RGBA_F16" : "ARGB_8888"; 125 | jclass bitmapConfig = env->FindClass("android/graphics/Bitmap$Config"); 126 | jfieldID rgba8888FieldID = env->GetStaticFieldID(bitmapConfig, 127 | bitmapPixelConfig.c_str(), 128 | "Landroid/graphics/Bitmap$Config;"); 129 | jobject rgba8888Obj = env->GetStaticObjectField(bitmapConfig, rgba8888FieldID); 130 | 131 | jclass bitmapClass = env->FindClass("android/graphics/Bitmap"); 132 | jmethodID createBitmapMethodID = env->GetStaticMethodID(bitmapClass, "createBitmap", 133 | "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;"); 134 | jobject bitmapObj = env->CallStaticObjectMethod(bitmapClass, createBitmapMethodID, 135 | static_cast(dst_width), 136 | static_cast(dst_height), 137 | rgba8888Obj); 138 | 139 | 140 | if (AndroidBitmap_getInfo(env, bitmapObj, &info) < 0) { 141 | throwPixelsException(env); 142 | return static_cast(nullptr); 143 | } 144 | 145 | addr = nullptr; 146 | 147 | if (AndroidBitmap_lockPixels(env, bitmapObj, &addr) != 0) { 148 | throwPixelsException(env); 149 | return static_cast(nullptr); 150 | } 151 | 152 | coder::CopyUnalignedRGBA(reinterpret_cast(output.data()), dstStride, 153 | reinterpret_cast(addr), (int) info.stride, 154 | (int) info.width, 155 | (int) info.height, useFloat16 ? 2 : 1); 156 | 157 | if (AndroidBitmap_unlockPixels(env, bitmapObj) != 0) { 158 | throwPixelsException(env); 159 | return static_cast(nullptr); 160 | } 161 | 162 | rgbaPixels.clear(); 163 | 164 | return bitmapObj; 165 | } -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/HalfFloats.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 04/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include "HalfFloats.h" 30 | #include 31 | #include <__threading_support> 32 | #include 33 | #include 34 | #include "half.hpp" 35 | 36 | using namespace std; 37 | 38 | #undef HWY_TARGET_INCLUDE 39 | #define HWY_TARGET_INCLUDE "HalfFloats.cpp" 40 | 41 | #include "hwy/foreach_target.h" 42 | #include "hwy/highway.h" 43 | 44 | using namespace half_float; 45 | 46 | uint as_uint(const float x) { 47 | return *(uint *) &x; 48 | } 49 | 50 | float as_float(const uint x) { 51 | return *(float *) &x; 52 | } 53 | 54 | uint16_t float_to_half( 55 | const float x) { // IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15, +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits 56 | const uint b = 57 | as_uint(x) + 0x00001000; // round-to-nearest-even: add last bit after truncated mantissa 58 | const uint e = (b & 0x7F800000) >> 23; // exponent 59 | const uint m = b & 60 | 0x007FFFFF; // mantissa; in line below: 0x007FF000 = 0x00800000-0x00001000 = decimal indicator flag - initial rounding 61 | return (b & 0x80000000) >> 16 | (e > 112) * ((((e - 112) << 10) & 0x7C00) | m >> 13) | 62 | ((e < 113) & (e > 101)) * ((((0x007FF000 + m) >> (125 - e)) + 1) >> 1) | 63 | (e > 143) * 0x7FFF; // sign : normalized : denormalized : saturate 64 | } 65 | 66 | float half_to_float( 67 | const uint16_t x) { // IEEE-754 16-bit floating-point format (without infinity): 1-5-10, exp-15, +-131008.0, +-6.1035156E-5, +-5.9604645E-8, 3.311 digits 68 | // const uint e = (x & 0x7C00) >> 10; // exponent 69 | // const uint m = (x & 0x03FF) << 13; // mantissa 70 | // const uint v = as_uint((float) m) 71 | // >> 23; // evil log2 bit hack to count leading zeros in denormalized format 72 | // return as_float((x & 0x8000) << 16 | (e != 0) * ((e + 112) << 23 | m) | ((e == 0) & (m != 0)) * 73 | // ((v - 37) << 23 | 74 | // ((m << (150 - v)) & 75 | // 0x007FE000))); // sign : normalized : denormalized 76 | half f; 77 | f.data_ = x; 78 | return f; 79 | } 80 | 81 | HWY_BEFORE_NAMESPACE(); 82 | 83 | namespace coder::HWY_NAMESPACE { 84 | 85 | using hwy::HWY_NAMESPACE::FixedTag; 86 | using hwy::HWY_NAMESPACE::Vec; 87 | using hwy::HWY_NAMESPACE::LoadInterleaved4; 88 | using hwy::HWY_NAMESPACE::Rebind; 89 | using hwy::HWY_NAMESPACE::Store; 90 | using hwy::HWY_NAMESPACE::BitCast; 91 | using hwy::HWY_NAMESPACE::StoreInterleaved4; 92 | 93 | void RGBAF32ToF16RowHWY(const float *HWY_RESTRICT src, uint16_t *dst, int width) { 94 | const FixedTag df32; 95 | const FixedTag df16; 96 | const FixedTag du16; 97 | using V32 = Vec; 98 | using V16 = Vec; 99 | const Rebind> dfc16; 100 | int x = 0; 101 | int pixelsCount = 4; 102 | for (x = 0; x + pixelsCount < width; x += pixelsCount) { 103 | V32 pixels1; 104 | V32 pixels2; 105 | V32 pixels3; 106 | V32 pixels4; 107 | LoadInterleaved4(df32, src, pixels1, pixels2, pixels3, pixels4); 108 | auto pixeld1 = BitCast(du16, DemoteTo(dfc16, pixels1)); 109 | auto pixeld2 = BitCast(du16, DemoteTo(dfc16, pixels2)); 110 | auto pixeld3 = BitCast(du16, DemoteTo(dfc16, pixels3)); 111 | auto pixeld4 = BitCast(du16, DemoteTo(dfc16, pixels4)); 112 | StoreInterleaved4(pixeld1, pixeld2, pixeld3, pixeld4, du16, 113 | reinterpret_cast(dst)); 114 | src += 4 * pixelsCount; 115 | dst += 4 * pixelsCount; 116 | } 117 | 118 | for (; x < width; ++x) { 119 | dst[0] = half(src[0]).data_; 120 | dst[1] = half(src[1]).data_; 121 | dst[2] = half(src[2]).data_; 122 | dst[3] = half(src[3]).data_; 123 | 124 | src += 4; 125 | dst += 4; 126 | } 127 | } 128 | 129 | void 130 | RgbaF32ToF16H(const float *HWY_RESTRICT src, int srcStride, uint16_t *HWY_RESTRICT dst, 131 | int dstStride, int width, 132 | int height) { 133 | auto srcPixels = reinterpret_cast(src); 134 | auto dstPixels = reinterpret_cast(dst); 135 | 136 | int threadCount = clamp(min(static_cast(std::thread::hardware_concurrency()), 137 | width * height / (256 * 256)), 1, 12); 138 | std::vector workers; 139 | 140 | int segmentHeight = height / threadCount; 141 | 142 | for (int i = 0; i < threadCount; i++) { 143 | int start = i * segmentHeight; 144 | int end = (i + 1) * segmentHeight; 145 | if (i == threadCount - 1) { 146 | end = height; 147 | } 148 | workers.emplace_back( 149 | [start, end, srcPixels, dstPixels, srcStride, dstStride, width]() { 150 | for (int y = start; y < end; ++y) { 151 | RGBAF32ToF16RowHWY( 152 | reinterpret_cast(srcPixels + srcStride * y), 153 | reinterpret_cast(dstPixels + dstStride * y), 154 | width); 155 | } 156 | }); 157 | } 158 | 159 | for (std::thread &thread: workers) { 160 | thread.join(); 161 | } 162 | } 163 | } 164 | 165 | HWY_AFTER_NAMESPACE(); 166 | 167 | #if HWY_ONCE 168 | 169 | namespace coder { 170 | HWY_EXPORT(RgbaF32ToF16H); 171 | HWY_DLLEXPORT void 172 | RgbaF32ToF16(const float *HWY_RESTRICT src, int srcStride, uint16_t *HWY_RESTRICT dst, 173 | int dstStride, int width, 174 | int height) { 175 | HWY_DYNAMIC_DISPATCH(RgbaF32ToF16H)(src, srcStride, dst, dstStride, width, height); 176 | } 177 | } 178 | 179 | #endif -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/CopyUnaligned.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 12/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include "CopyUnaligned.h" 30 | #include 31 | #include 32 | 33 | using namespace std; 34 | 35 | #undef HWY_TARGET_INCLUDE 36 | #define HWY_TARGET_INCLUDE "CopyUnalignedRGBA.cpp" 37 | 38 | #include "hwy/foreach_target.h" 39 | #include "hwy/highway.h" 40 | 41 | HWY_BEFORE_NAMESPACE(); 42 | 43 | namespace coder::HWY_NAMESPACE { 44 | 45 | using hwy::HWY_NAMESPACE::ScalableTag; 46 | using hwy::HWY_NAMESPACE::StoreU; 47 | using hwy::HWY_NAMESPACE::LoadU; 48 | using hwy::HWY_NAMESPACE::Vec; 49 | using hwy::HWY_NAMESPACE::TFromD; 50 | 51 | template> 52 | void 53 | CopyUnalignedRGBARow(const D d, const Buf *HWY_RESTRICT src, Buf *HWY_RESTRICT dst, int width) { 54 | int x = 0; 55 | using VU = Vec; 56 | int pixels = d.MaxLanes() / 4; 57 | for (x = 0; x + pixels < width; x += pixels) { 58 | VU pixel = LoadU(d, src); 59 | StoreU(pixel, d, dst); 60 | 61 | src += pixels * 4; 62 | dst += pixels * 4; 63 | } 64 | 65 | for (; x < width; ++x) { 66 | auto p1 = src[0]; 67 | auto p2 = src[1]; 68 | auto p3 = src[2]; 69 | auto p4 = src[3]; 70 | 71 | dst[0] = p1; 72 | dst[1] = p2; 73 | dst[2] = p3; 74 | dst[3] = p4; 75 | 76 | src += 4; 77 | dst += 4; 78 | } 79 | } 80 | 81 | void CopyUnalignedRGB565Row(const uint16_t *HWY_RESTRICT src, uint16_t *HWY_RESTRICT dst, 82 | int width) { 83 | int x = 0; 84 | const ScalableTag du; 85 | using VU = Vec; 86 | int pixels = du.MaxLanes(); 87 | for (x = 0; x + pixels < width; x += pixels) { 88 | VU pixel = LoadU(du, src); 89 | StoreU(pixel, du, dst); 90 | 91 | src += pixels; 92 | dst += pixels; 93 | } 94 | 95 | for (; x < width; ++x) { 96 | auto p1 = src[0]; 97 | dst[0] = p1; 98 | src += 1; 99 | dst += 1; 100 | } 101 | } 102 | 103 | void 104 | CopyUnalignedRGB565(const uint8_t *HWY_RESTRICT src, int srcStride, uint8_t *HWY_RESTRICT dst, 105 | int dstStride, int width, 106 | int height) { 107 | for (int y = 0; y < height; y++) { 108 | CopyUnalignedRGB565Row(reinterpret_cast(src + (y * srcStride)), 109 | reinterpret_cast(dst + (y * dstStride)), 110 | width); 111 | } 112 | } 113 | 114 | void 115 | CopyUnalignedRGBA(const uint8_t *HWY_RESTRICT src, int srcStride, uint8_t *HWY_RESTRICT dst, 116 | int dstStride, int width, 117 | int height, 118 | int pixelSize) { 119 | 120 | int threadCount = clamp(min(static_cast(std::thread::hardware_concurrency()), 121 | width * height / (256 * 256)), 1, 12); 122 | vector workers; 123 | 124 | int segmentHeight = height / threadCount; 125 | 126 | for (int i = 0; i < threadCount; i++) { 127 | int start = i * segmentHeight; 128 | int end = (i + 1) * segmentHeight; 129 | if (i == threadCount - 1) { 130 | end = height; 131 | } 132 | workers.emplace_back([start, end, src, dst, srcStride, dstStride, width, pixelSize]() { 133 | for (int y = start; y < end; ++y) { 134 | if (pixelSize == 1) { 135 | const ScalableTag du8; 136 | auto fn = CopyUnalignedRGBARow; 137 | fn(du8, 138 | reinterpret_cast(src + (y * srcStride)), 139 | reinterpret_cast(dst + (y * dstStride)), 140 | width); 141 | } else if (pixelSize == 2) { 142 | const ScalableTag du16; 143 | auto fn = CopyUnalignedRGBARow; 144 | fn(du16, 145 | reinterpret_cast(src + 146 | (y * srcStride)), 147 | reinterpret_cast(dst + (y * dstStride)), 148 | width); 149 | } else if (pixelSize == 4) { 150 | const ScalableTag df32; 151 | auto fn = CopyUnalignedRGBARow; 152 | fn(df32, 153 | reinterpret_cast(src + 154 | (y * srcStride)), 155 | reinterpret_cast(dst + (y * dstStride)), 156 | width); 157 | } 158 | } 159 | }); 160 | } 161 | 162 | for (std::thread &thread: workers) { 163 | thread.join(); 164 | } 165 | } 166 | 167 | } 168 | 169 | HWY_AFTER_NAMESPACE(); 170 | 171 | #if HWY_ONCE 172 | namespace coder { 173 | HWY_EXPORT(CopyUnalignedRGBA); 174 | HWY_EXPORT(CopyUnalignedRGB565); 175 | 176 | HWY_DLLEXPORT void 177 | CopyUnalignedRGBA(const uint8_t *HWY_RESTRICT src, int srcStride, uint8_t *HWY_RESTRICT dst, 178 | int dstStride, int width, 179 | int height, 180 | int pixelSize) { 181 | HWY_DYNAMIC_DISPATCH(CopyUnalignedRGBA)(src, srcStride, dst, dstStride, width, height, 182 | pixelSize); 183 | } 184 | 185 | HWY_DLLEXPORT void 186 | CopyUnalignedRGB565(const uint8_t *HWY_RESTRICT src, int srcStride, uint8_t *HWY_RESTRICT dst, 187 | int dstStride, int width, 188 | int height) { 189 | HWY_DYNAMIC_DISPATCH(CopyUnalignedRGB565)(src, srcStride, dst, dstStride, width, height); 190 | } 191 | } 192 | #endif -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/rotate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_ROTATE_H_ 12 | #define INCLUDE_LIBYUV_ROTATE_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | // Supported rotation. 22 | typedef enum RotationMode { 23 | kRotate0 = 0, // No rotation. 24 | kRotate90 = 90, // Rotate 90 degrees clockwise. 25 | kRotate180 = 180, // Rotate 180 degrees. 26 | kRotate270 = 270, // Rotate 270 degrees clockwise. 27 | 28 | // Deprecated. 29 | kRotateNone = 0, 30 | kRotateClockwise = 90, 31 | kRotateCounterClockwise = 270, 32 | } RotationModeEnum; 33 | 34 | // Rotate I420 frame. 35 | LIBYUV_API 36 | int I420Rotate(const uint8_t* src_y, 37 | int src_stride_y, 38 | const uint8_t* src_u, 39 | int src_stride_u, 40 | const uint8_t* src_v, 41 | int src_stride_v, 42 | uint8_t* dst_y, 43 | int dst_stride_y, 44 | uint8_t* dst_u, 45 | int dst_stride_u, 46 | uint8_t* dst_v, 47 | int dst_stride_v, 48 | int width, 49 | int height, 50 | enum RotationMode mode); 51 | 52 | // Rotate I422 frame. 53 | LIBYUV_API 54 | int I422Rotate(const uint8_t* src_y, 55 | int src_stride_y, 56 | const uint8_t* src_u, 57 | int src_stride_u, 58 | const uint8_t* src_v, 59 | int src_stride_v, 60 | uint8_t* dst_y, 61 | int dst_stride_y, 62 | uint8_t* dst_u, 63 | int dst_stride_u, 64 | uint8_t* dst_v, 65 | int dst_stride_v, 66 | int width, 67 | int height, 68 | enum RotationMode mode); 69 | 70 | // Rotate I444 frame. 71 | LIBYUV_API 72 | int I444Rotate(const uint8_t* src_y, 73 | int src_stride_y, 74 | const uint8_t* src_u, 75 | int src_stride_u, 76 | const uint8_t* src_v, 77 | int src_stride_v, 78 | uint8_t* dst_y, 79 | int dst_stride_y, 80 | uint8_t* dst_u, 81 | int dst_stride_u, 82 | uint8_t* dst_v, 83 | int dst_stride_v, 84 | int width, 85 | int height, 86 | enum RotationMode mode); 87 | 88 | // Rotate NV12 input and store in I420. 89 | LIBYUV_API 90 | int NV12ToI420Rotate(const uint8_t* src_y, 91 | int src_stride_y, 92 | const uint8_t* src_uv, 93 | int src_stride_uv, 94 | uint8_t* dst_y, 95 | int dst_stride_y, 96 | uint8_t* dst_u, 97 | int dst_stride_u, 98 | uint8_t* dst_v, 99 | int dst_stride_v, 100 | int width, 101 | int height, 102 | enum RotationMode mode); 103 | 104 | // Convert Android420 to I420 with rotation. 105 | // "rotation" can be 0, 90, 180 or 270. 106 | LIBYUV_API 107 | int Android420ToI420Rotate(const uint8_t* src_y, 108 | int src_stride_y, 109 | const uint8_t* src_u, 110 | int src_stride_u, 111 | const uint8_t* src_v, 112 | int src_stride_v, 113 | int src_pixel_stride_uv, 114 | uint8_t* dst_y, 115 | int dst_stride_y, 116 | uint8_t* dst_u, 117 | int dst_stride_u, 118 | uint8_t* dst_v, 119 | int dst_stride_v, 120 | int width, 121 | int height, 122 | enum RotationMode rotation); 123 | 124 | // Rotate a plane by 0, 90, 180, or 270. 125 | LIBYUV_API 126 | int RotatePlane(const uint8_t* src, 127 | int src_stride, 128 | uint8_t* dst, 129 | int dst_stride, 130 | int width, 131 | int height, 132 | enum RotationMode mode); 133 | 134 | // Rotate planes by 90, 180, 270. Deprecated. 135 | LIBYUV_API 136 | void RotatePlane90(const uint8_t* src, 137 | int src_stride, 138 | uint8_t* dst, 139 | int dst_stride, 140 | int width, 141 | int height); 142 | 143 | LIBYUV_API 144 | void RotatePlane180(const uint8_t* src, 145 | int src_stride, 146 | uint8_t* dst, 147 | int dst_stride, 148 | int width, 149 | int height); 150 | 151 | LIBYUV_API 152 | void RotatePlane270(const uint8_t* src, 153 | int src_stride, 154 | uint8_t* dst, 155 | int dst_stride, 156 | int width, 157 | int height); 158 | 159 | // Rotations for when U and V are interleaved. 160 | // These functions take one UV input pointer and 161 | // split the data into two buffers while 162 | // rotating them. 163 | // width and height expected to be half size for NV12. 164 | LIBYUV_API 165 | int SplitRotateUV(const uint8_t* src_uv, 166 | int src_stride_uv, 167 | uint8_t* dst_u, 168 | int dst_stride_u, 169 | uint8_t* dst_v, 170 | int dst_stride_v, 171 | int width, 172 | int height, 173 | enum RotationMode mode); 174 | 175 | LIBYUV_API 176 | void SplitRotateUV90(const uint8_t* src, 177 | int src_stride, 178 | uint8_t* dst_a, 179 | int dst_stride_a, 180 | uint8_t* dst_b, 181 | int dst_stride_b, 182 | int width, 183 | int height); 184 | 185 | LIBYUV_API 186 | void SplitRotateUV180(const uint8_t* src, 187 | int src_stride, 188 | uint8_t* dst_a, 189 | int dst_stride_a, 190 | uint8_t* dst_b, 191 | int dst_stride_b, 192 | int width, 193 | int height); 194 | 195 | LIBYUV_API 196 | void SplitRotateUV270(const uint8_t* src, 197 | int src_stride, 198 | uint8_t* dst_a, 199 | int dst_stride_a, 200 | uint8_t* dst_b, 201 | int dst_stride_b, 202 | int width, 203 | int height); 204 | 205 | // The 90 and 270 functions are based on transposes. 206 | // Doing a transpose with reversing the read/write 207 | // order will result in a rotation by +- 90 degrees. 208 | // Deprecated. 209 | LIBYUV_API 210 | void TransposePlane(const uint8_t* src, 211 | int src_stride, 212 | uint8_t* dst, 213 | int dst_stride, 214 | int width, 215 | int height); 216 | 217 | LIBYUV_API 218 | void SplitTransposeUV(const uint8_t* src, 219 | int src_stride, 220 | uint8_t* dst_a, 221 | int dst_stride_a, 222 | uint8_t* dst_b, 223 | int dst_stride_b, 224 | int width, 225 | int height); 226 | 227 | #ifdef __cplusplus 228 | } // extern "C" 229 | } // namespace libyuv 230 | #endif 231 | 232 | #endif // INCLUDE_LIBYUV_ROTATE_H_ 233 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/Rgb1010102toF16.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * MIT License 3 | * 4 | * Copyright (c) 2023 Radzivon Bartoshyk 5 | * jxl-coder [https://github.com/awxkee/jxl-coder] 6 | * 7 | * Created by Radzivon Bartoshyk on 05/09/2023 8 | * 9 | * Permission is hereby granted, free of charge, to any person obtaining a copy 10 | * of this software and associated documentation files (the "Software"), to deal 11 | * in the Software without restriction, including without limitation the rights 12 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | * copies of the Software, and to permit persons to whom the Software is 14 | * furnished to do so, subject to the following conditions: 15 | * 16 | * The above copyright notice and this permission notice shall be included in all 17 | * copies or substantial portions of the Software. 18 | * 19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | * SOFTWARE. 26 | * 27 | */ 28 | 29 | #include "Rgb1010102toF16.h" 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include "half.hpp" 36 | 37 | using namespace half_float; 38 | using namespace std; 39 | 40 | #undef HWY_TARGET_INCLUDE 41 | #define HWY_TARGET_INCLUDE "Rgb1010102toF16.cpp" 42 | 43 | #include "hwy/foreach_target.h" 44 | #include "hwy/highway.h" 45 | 46 | HWY_BEFORE_NAMESPACE(); 47 | 48 | namespace coder::HWY_NAMESPACE { 49 | 50 | using hwy::HWY_NAMESPACE::FixedTag; 51 | using hwy::HWY_NAMESPACE::Vec; 52 | using hwy::HWY_NAMESPACE::LoadU; 53 | using hwy::float16_t; 54 | using hwy::HWY_NAMESPACE::RebindToFloat; 55 | using hwy::HWY_NAMESPACE::Rebind; 56 | using hwy::HWY_NAMESPACE::ShiftRight; 57 | using hwy::HWY_NAMESPACE::ShiftRightSame; 58 | using hwy::HWY_NAMESPACE::Set; 59 | using hwy::HWY_NAMESPACE::And; 60 | using hwy::HWY_NAMESPACE::ConvertTo; 61 | using hwy::HWY_NAMESPACE::DemoteTo; 62 | using hwy::HWY_NAMESPACE::StoreInterleaved4; 63 | using hwy::HWY_NAMESPACE::Div; 64 | using hwy::HWY_NAMESPACE::BitCast; 65 | using hwy::float16_t; 66 | 67 | void 68 | ConvertRGBA1010102toF16HWYRow(const uint8_t *HWY_RESTRICT src, uint16_t *HWY_RESTRICT dst, 69 | int width, bool littleEndian) { 70 | 71 | const FixedTag du32; 72 | const FixedTag df32; 73 | const FixedTag du16; 74 | 75 | using VU32 = Vec; 76 | 77 | auto dstPointer = reinterpret_cast(dst); 78 | auto srcPointer = reinterpret_cast(src); 79 | 80 | auto mask = Set(du32, (1u << 10u) - 1u); 81 | 82 | int x = 0; 83 | 84 | const Rebind dfc16; 85 | const RebindToFloat dfcf16; 86 | 87 | auto maxColors = (float) (powf(2.0f, 10.0f) - 1.0f); 88 | auto maxColorsF32 = Set(df32, maxColors); 89 | auto maxColorsAF32 = Set(df32, 3.0f); 90 | 91 | for (; x + 4 < width; x += 4) { 92 | VU32 color1010102 = LoadU(du32, reinterpret_cast(srcPointer)); 93 | auto RF = ConvertTo(dfcf16, And(ShiftRight<20>(color1010102), mask)); 94 | auto RF16 = DemoteTo(dfc16, Div(RF, maxColorsF32)); 95 | auto GF = ConvertTo(dfcf16, And(ShiftRight<10>(color1010102), mask)); 96 | auto GF16 = DemoteTo(dfc16, Div(GF, maxColorsF32)); 97 | auto BF = ConvertTo(dfcf16, And(color1010102, mask)); 98 | auto BF16 = DemoteTo(dfc16, Div(BF, maxColorsF32)); 99 | auto AU = ConvertTo(dfcf16, And(ShiftRight<30>(color1010102), mask)); 100 | auto AF16 = DemoteTo(dfc16, Div(AU, maxColorsAF32)); 101 | StoreInterleaved4(BitCast(du16, BF16), 102 | BitCast(du16, GF16), 103 | BitCast(du16, RF16), 104 | BitCast(du16, AF16), 105 | du16, 106 | reinterpret_cast(dstPointer)); 107 | 108 | srcPointer += 4; 109 | dstPointer += 4 * 4; 110 | } 111 | 112 | for (; x < width; ++x) { 113 | uint32_t rgba1010102 = reinterpret_cast(srcPointer)[0]; 114 | 115 | const uint32_t scalarMask = (1u << 10u) - 1u; 116 | uint32_t b = (rgba1010102) & scalarMask; 117 | uint32_t g = (rgba1010102 >> 10) & scalarMask; 118 | uint32_t r = (rgba1010102 >> 20) & scalarMask; 119 | uint32_t a = (rgba1010102 >> 30) * 3; // Replicate 2 bits to 8 bits. 120 | 121 | // Convert each channel to floating-point values 122 | float rFloat = static_cast(r) / 1023.0f; 123 | float gFloat = static_cast(g) / 1023.0f; 124 | float bFloat = static_cast(b) / 1023.0f; 125 | float aFloat = static_cast(a) / 3.0f; 126 | 127 | auto dstCast = reinterpret_cast(dstPointer); 128 | if (littleEndian) { 129 | dstCast[0] = half(bFloat).data_; 130 | dstCast[1] = half(gFloat).data_; 131 | dstCast[2] = half(rFloat).data_; 132 | dstCast[3] = half(aFloat).data_; 133 | } else { 134 | dstCast[0] = half(rFloat).data_; 135 | dstCast[1] = half(gFloat).data_; 136 | dstCast[2] = half(bFloat).data_; 137 | dstCast[3] = half(aFloat).data_; 138 | } 139 | 140 | srcPointer += 1; 141 | dstPointer += 4; 142 | } 143 | } 144 | 145 | void 146 | ConvertRGBA1010102toF16(const uint8_t *src, int srcStride, uint16_t *dst, int dstStride, 147 | int width, int height) { 148 | auto mDstPointer = reinterpret_cast(dst); 149 | auto mSrcPointer = reinterpret_cast(src); 150 | 151 | uint32_t testValue = 0x01020304; 152 | auto testBytes = reinterpret_cast(&testValue); 153 | 154 | bool littleEndian = false; 155 | if (testBytes[0] == 0x04) { 156 | littleEndian = true; 157 | } else if (testBytes[0] == 0x01) { 158 | littleEndian = false; 159 | } 160 | 161 | int threadCount = clamp(min(static_cast(std::thread::hardware_concurrency()), 162 | width * height / (256 * 256)), 1, 12); 163 | vector workers; 164 | 165 | int segmentHeight = height / threadCount; 166 | 167 | for (int i = 0; i < threadCount; i++) { 168 | int start = i * segmentHeight; 169 | int end = (i + 1) * segmentHeight; 170 | if (i == threadCount - 1) { 171 | end = height; 172 | } 173 | workers.emplace_back( 174 | [start, end, mSrcPointer, mDstPointer, srcStride, dstStride, littleEndian, width]() { 175 | for (int y = start; y < end; ++y) { 176 | ConvertRGBA1010102toF16HWYRow( 177 | reinterpret_cast(mSrcPointer + y * srcStride), 178 | reinterpret_cast(mDstPointer + y * dstStride), 179 | width, 180 | littleEndian); 181 | } 182 | }); 183 | } 184 | 185 | for (std::thread &thread: workers) { 186 | thread.join(); 187 | } 188 | } 189 | 190 | } 191 | 192 | HWY_AFTER_NAMESPACE(); 193 | 194 | // Conversion function from 1010102 to half floats 195 | 196 | #if HWY_ONCE 197 | 198 | namespace coder { 199 | HWY_EXPORT(ConvertRGBA1010102toF16); 200 | 201 | HWY_DLLEXPORT void 202 | ConvertRGBA1010102toF16(const uint8_t *src, int srcStride, uint16_t *dst, int dstStride, 203 | int width, int height) { 204 | HWY_DYNAMIC_DISPATCH(ConvertRGBA1010102toF16)(src, srcStride, dst, dstStride, width, 205 | height); 206 | } 207 | } 208 | 209 | #endif -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/rotate_row.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_ROTATE_ROW_H_ 12 | #define INCLUDE_LIBYUV_ROTATE_ROW_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | #if defined(__pnacl__) || defined(__CLR_VER) || \ 22 | (defined(__native_client__) && defined(__x86_64__)) || \ 23 | (defined(__i386__) && !defined(__SSE__) && !defined(__clang__)) 24 | #define LIBYUV_DISABLE_X86 25 | #endif 26 | #if defined(__native_client__) 27 | #define LIBYUV_DISABLE_NEON 28 | #endif 29 | // MemorySanitizer does not support assembly code yet. http://crbug.com/344505 30 | #if defined(__has_feature) 31 | #if __has_feature(memory_sanitizer) 32 | #define LIBYUV_DISABLE_X86 33 | #endif 34 | #endif 35 | // The following are available for Visual C 32 bit: 36 | #if !defined(LIBYUV_DISABLE_X86) && defined(_M_IX86) && defined(_MSC_VER) && \ 37 | !defined(__clang__) 38 | #define HAS_TRANSPOSEWX8_SSSE3 39 | #define HAS_TRANSPOSEUVWX8_SSE2 40 | #endif 41 | 42 | // The following are available for GCC 32 or 64 bit: 43 | #if !defined(LIBYUV_DISABLE_X86) && (defined(__i386__) || defined(__x86_64__)) 44 | #define HAS_TRANSPOSEWX8_SSSE3 45 | #endif 46 | 47 | // The following are available for 64 bit GCC: 48 | #if !defined(LIBYUV_DISABLE_X86) && defined(__x86_64__) 49 | #define HAS_TRANSPOSEWX8_FAST_SSSE3 50 | #define HAS_TRANSPOSEUVWX8_SSE2 51 | #endif 52 | 53 | #if !defined(LIBYUV_DISABLE_NEON) && \ 54 | (defined(__ARM_NEON__) || defined(LIBYUV_NEON) || defined(__aarch64__)) 55 | #define HAS_TRANSPOSEWX8_NEON 56 | #define HAS_TRANSPOSEUVWX8_NEON 57 | #endif 58 | 59 | #if !defined(LIBYUV_DISABLE_MSA) && defined(__mips_msa) 60 | #define HAS_TRANSPOSEWX16_MSA 61 | #define HAS_TRANSPOSEUVWX16_MSA 62 | #endif 63 | 64 | #if !defined(LIBYUV_DISABLE_LSX) && defined(__loongarch_sx) 65 | #define HAS_TRANSPOSEWX16_LSX 66 | #define HAS_TRANSPOSEUVWX16_LSX 67 | #endif 68 | 69 | void TransposeWxH_C(const uint8_t* src, 70 | int src_stride, 71 | uint8_t* dst, 72 | int dst_stride, 73 | int width, 74 | int height); 75 | 76 | void TransposeWx8_C(const uint8_t* src, 77 | int src_stride, 78 | uint8_t* dst, 79 | int dst_stride, 80 | int width); 81 | void TransposeWx16_C(const uint8_t* src, 82 | int src_stride, 83 | uint8_t* dst, 84 | int dst_stride, 85 | int width); 86 | void TransposeWx8_NEON(const uint8_t* src, 87 | int src_stride, 88 | uint8_t* dst, 89 | int dst_stride, 90 | int width); 91 | void TransposeWx8_SSSE3(const uint8_t* src, 92 | int src_stride, 93 | uint8_t* dst, 94 | int dst_stride, 95 | int width); 96 | void TransposeWx8_Fast_SSSE3(const uint8_t* src, 97 | int src_stride, 98 | uint8_t* dst, 99 | int dst_stride, 100 | int width); 101 | void TransposeWx16_MSA(const uint8_t* src, 102 | int src_stride, 103 | uint8_t* dst, 104 | int dst_stride, 105 | int width); 106 | void TransposeWx16_LSX(const uint8_t* src, 107 | int src_stride, 108 | uint8_t* dst, 109 | int dst_stride, 110 | int width); 111 | 112 | void TransposeWx8_Any_NEON(const uint8_t* src, 113 | int src_stride, 114 | uint8_t* dst, 115 | int dst_stride, 116 | int width); 117 | void TransposeWx8_Any_SSSE3(const uint8_t* src, 118 | int src_stride, 119 | uint8_t* dst, 120 | int dst_stride, 121 | int width); 122 | void TransposeWx8_Fast_Any_SSSE3(const uint8_t* src, 123 | int src_stride, 124 | uint8_t* dst, 125 | int dst_stride, 126 | int width); 127 | void TransposeWx16_Any_MSA(const uint8_t* src, 128 | int src_stride, 129 | uint8_t* dst, 130 | int dst_stride, 131 | int width); 132 | void TransposeWx16_Any_LSX(const uint8_t* src, 133 | int src_stride, 134 | uint8_t* dst, 135 | int dst_stride, 136 | int width); 137 | 138 | void TransposeUVWxH_C(const uint8_t* src, 139 | int src_stride, 140 | uint8_t* dst_a, 141 | int dst_stride_a, 142 | uint8_t* dst_b, 143 | int dst_stride_b, 144 | int width, 145 | int height); 146 | 147 | void TransposeUVWx8_C(const uint8_t* src, 148 | int src_stride, 149 | uint8_t* dst_a, 150 | int dst_stride_a, 151 | uint8_t* dst_b, 152 | int dst_stride_b, 153 | int width); 154 | void TransposeUVWx16_C(const uint8_t* src, 155 | int src_stride, 156 | uint8_t* dst_a, 157 | int dst_stride_a, 158 | uint8_t* dst_b, 159 | int dst_stride_b, 160 | int width); 161 | void TransposeUVWx8_SSE2(const uint8_t* src, 162 | int src_stride, 163 | uint8_t* dst_a, 164 | int dst_stride_a, 165 | uint8_t* dst_b, 166 | int dst_stride_b, 167 | int width); 168 | void TransposeUVWx8_NEON(const uint8_t* src, 169 | int src_stride, 170 | uint8_t* dst_a, 171 | int dst_stride_a, 172 | uint8_t* dst_b, 173 | int dst_stride_b, 174 | int width); 175 | void TransposeUVWx16_MSA(const uint8_t* src, 176 | int src_stride, 177 | uint8_t* dst_a, 178 | int dst_stride_a, 179 | uint8_t* dst_b, 180 | int dst_stride_b, 181 | int width); 182 | void TransposeUVWx16_LSX(const uint8_t* src, 183 | int src_stride, 184 | uint8_t* dst_a, 185 | int dst_stride_a, 186 | uint8_t* dst_b, 187 | int dst_stride_b, 188 | int width); 189 | 190 | void TransposeUVWx8_Any_SSE2(const uint8_t* src, 191 | int src_stride, 192 | uint8_t* dst_a, 193 | int dst_stride_a, 194 | uint8_t* dst_b, 195 | int dst_stride_b, 196 | int width); 197 | void TransposeUVWx8_Any_NEON(const uint8_t* src, 198 | int src_stride, 199 | uint8_t* dst_a, 200 | int dst_stride_a, 201 | uint8_t* dst_b, 202 | int dst_stride_b, 203 | int width); 204 | void TransposeUVWx16_Any_MSA(const uint8_t* src, 205 | int src_stride, 206 | uint8_t* dst_a, 207 | int dst_stride_a, 208 | uint8_t* dst_b, 209 | int dst_stride_b, 210 | int width); 211 | void TransposeUVWx16_Any_LSX(const uint8_t* src, 212 | int src_stride, 213 | uint8_t* dst_a, 214 | int dst_stride_a, 215 | uint8_t* dst_b, 216 | int dst_stride_b, 217 | int width); 218 | 219 | #ifdef __cplusplus 220 | } // extern "C" 221 | } // namespace libyuv 222 | #endif 223 | 224 | #endif // INCLUDE_LIBYUV_ROTATE_ROW_H_ 225 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/aligned_allocator.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_ALIGNED_ALLOCATOR_H_ 17 | #define HIGHWAY_HWY_ALIGNED_ALLOCATOR_H_ 18 | 19 | // Memory allocator with support for alignment and offsets. 20 | 21 | #include 22 | #include 23 | 24 | #include "hwy/base.h" 25 | 26 | namespace hwy { 27 | 28 | // Minimum alignment of allocated memory for use in HWY_ASSUME_ALIGNED, which 29 | // requires a literal. This matches typical L1 cache line sizes, which prevents 30 | // false sharing. 31 | #define HWY_ALIGNMENT 64 32 | 33 | // Pointers to functions equivalent to malloc/free with an opaque void* passed 34 | // to them. 35 | using AllocPtr = void* (*)(void* opaque, size_t bytes); 36 | using FreePtr = void (*)(void* opaque, void* memory); 37 | 38 | // Returns null or a pointer to at least `payload_size` (which can be zero) 39 | // bytes of newly allocated memory, aligned to the larger of HWY_ALIGNMENT and 40 | // the vector size. Calls `alloc` with the passed `opaque` pointer to obtain 41 | // memory or malloc() if it is null. 42 | HWY_DLLEXPORT void* AllocateAlignedBytes(size_t payload_size, 43 | AllocPtr alloc_ptr, void* opaque_ptr); 44 | 45 | // Frees all memory. No effect if `aligned_pointer` == nullptr, otherwise it 46 | // must have been returned from a previous call to `AllocateAlignedBytes`. 47 | // Calls `free_ptr` with the passed `opaque_ptr` pointer to free the memory; if 48 | // `free_ptr` function is null, uses the default free(). 49 | HWY_DLLEXPORT void FreeAlignedBytes(const void* aligned_pointer, 50 | FreePtr free_ptr, void* opaque_ptr); 51 | 52 | // Class that deletes the aligned pointer passed to operator() calling the 53 | // destructor before freeing the pointer. This is equivalent to the 54 | // std::default_delete but for aligned objects. For a similar deleter equivalent 55 | // to free() for aligned memory see AlignedFreer(). 56 | class AlignedDeleter { 57 | public: 58 | AlignedDeleter() : free_(nullptr), opaque_ptr_(nullptr) {} 59 | AlignedDeleter(FreePtr free_ptr, void* opaque_ptr) 60 | : free_(free_ptr), opaque_ptr_(opaque_ptr) {} 61 | 62 | template 63 | void operator()(T* aligned_pointer) const { 64 | return DeleteAlignedArray(aligned_pointer, free_, opaque_ptr_, 65 | TypedArrayDeleter); 66 | } 67 | 68 | private: 69 | template 70 | static void TypedArrayDeleter(void* ptr, size_t size_in_bytes) { 71 | size_t elems = size_in_bytes / sizeof(T); 72 | for (size_t i = 0; i < elems; i++) { 73 | // Explicitly call the destructor on each element. 74 | (static_cast(ptr) + i)->~T(); 75 | } 76 | } 77 | 78 | // Function prototype that calls the destructor for each element in a typed 79 | // array. TypeArrayDeleter would match this prototype. 80 | using ArrayDeleter = void (*)(void* t_ptr, size_t t_size); 81 | 82 | HWY_DLLEXPORT static void DeleteAlignedArray(void* aligned_pointer, 83 | FreePtr free_ptr, 84 | void* opaque_ptr, 85 | ArrayDeleter deleter); 86 | 87 | FreePtr free_; 88 | void* opaque_ptr_; 89 | }; 90 | 91 | // Unique pointer to T with custom aligned deleter. This can be a single 92 | // element U or an array of element if T is a U[]. The custom aligned deleter 93 | // will call the destructor on U or each element of a U[] in the array case. 94 | template 95 | using AlignedUniquePtr = std::unique_ptr; 96 | 97 | // Aligned memory equivalent of make_unique using the custom allocators 98 | // alloc/free with the passed `opaque` pointer. This function calls the 99 | // constructor with the passed Args... and calls the destructor of the object 100 | // when the AlignedUniquePtr is destroyed. 101 | template 102 | AlignedUniquePtr MakeUniqueAlignedWithAlloc(AllocPtr alloc, FreePtr free, 103 | void* opaque, Args&&... args) { 104 | T* ptr = static_cast(AllocateAlignedBytes(sizeof(T), alloc, opaque)); 105 | return AlignedUniquePtr(new (ptr) T(std::forward(args)...), 106 | AlignedDeleter(free, opaque)); 107 | } 108 | 109 | // Similar to MakeUniqueAlignedWithAlloc but using the default alloc/free 110 | // functions. 111 | template 112 | AlignedUniquePtr MakeUniqueAligned(Args&&... args) { 113 | T* ptr = static_cast(AllocateAlignedBytes( 114 | sizeof(T), /*alloc_ptr=*/nullptr, /*opaque_ptr=*/nullptr)); 115 | return AlignedUniquePtr(new (ptr) T(std::forward(args)...), 116 | AlignedDeleter()); 117 | } 118 | 119 | // Helpers for array allocators (avoids overflow) 120 | namespace detail { 121 | 122 | // Returns x such that 1u << x == n (if n is a power of two). 123 | static inline constexpr size_t ShiftCount(size_t n) { 124 | return (n <= 1) ? 0 : 1 + ShiftCount(n / 2); 125 | } 126 | 127 | template 128 | T* AllocateAlignedItems(size_t items, AllocPtr alloc_ptr, void* opaque_ptr) { 129 | constexpr size_t size = sizeof(T); 130 | 131 | constexpr bool is_pow2 = (size & (size - 1)) == 0; 132 | constexpr size_t bits = ShiftCount(size); 133 | static_assert(!is_pow2 || (1ull << bits) == size, "ShiftCount is incorrect"); 134 | 135 | const size_t bytes = is_pow2 ? items << bits : items * size; 136 | const size_t check = is_pow2 ? bytes >> bits : bytes / size; 137 | if (check != items) { 138 | return nullptr; // overflowed 139 | } 140 | return static_cast(AllocateAlignedBytes(bytes, alloc_ptr, opaque_ptr)); 141 | } 142 | 143 | } // namespace detail 144 | 145 | // Aligned memory equivalent of make_unique for array types using the 146 | // custom allocators alloc/free. This function calls the constructor with the 147 | // passed Args... on every created item. The destructor of each element will be 148 | // called when the AlignedUniquePtr is destroyed. 149 | template 150 | AlignedUniquePtr MakeUniqueAlignedArrayWithAlloc( 151 | size_t items, AllocPtr alloc, FreePtr free, void* opaque, Args&&... args) { 152 | T* ptr = detail::AllocateAlignedItems(items, alloc, opaque); 153 | if (ptr != nullptr) { 154 | for (size_t i = 0; i < items; i++) { 155 | new (ptr + i) T(std::forward(args)...); 156 | } 157 | } 158 | return AlignedUniquePtr(ptr, AlignedDeleter(free, opaque)); 159 | } 160 | 161 | template 162 | AlignedUniquePtr MakeUniqueAlignedArray(size_t items, Args&&... args) { 163 | return MakeUniqueAlignedArrayWithAlloc( 164 | items, nullptr, nullptr, nullptr, std::forward(args)...); 165 | } 166 | 167 | // Custom deleter for std::unique_ptr equivalent to using free() as a deleter 168 | // but for aligned memory. 169 | class AlignedFreer { 170 | public: 171 | // Pass address of this to ctor to skip deleting externally-owned memory. 172 | static void DoNothing(void* /*opaque*/, void* /*aligned_pointer*/) {} 173 | 174 | AlignedFreer() : free_(nullptr), opaque_ptr_(nullptr) {} 175 | AlignedFreer(FreePtr free_ptr, void* opaque_ptr) 176 | : free_(free_ptr), opaque_ptr_(opaque_ptr) {} 177 | 178 | template 179 | void operator()(T* aligned_pointer) const { 180 | // TODO(deymo): assert that we are using a POD type T. 181 | FreeAlignedBytes(aligned_pointer, free_, opaque_ptr_); 182 | } 183 | 184 | private: 185 | FreePtr free_; 186 | void* opaque_ptr_; 187 | }; 188 | 189 | // Unique pointer to single POD, or (if T is U[]) an array of POD. For non POD 190 | // data use AlignedUniquePtr. 191 | template 192 | using AlignedFreeUniquePtr = std::unique_ptr; 193 | 194 | // Allocate an aligned and uninitialized array of POD values as a unique_ptr. 195 | // Upon destruction of the unique_ptr the aligned array will be freed. 196 | template 197 | AlignedFreeUniquePtr AllocateAligned(const size_t items, AllocPtr alloc, 198 | FreePtr free, void* opaque) { 199 | return AlignedFreeUniquePtr( 200 | detail::AllocateAlignedItems(items, alloc, opaque), 201 | AlignedFreer(free, opaque)); 202 | } 203 | 204 | // Same as previous AllocateAligned(), using default allocate/free functions. 205 | template 206 | AlignedFreeUniquePtr AllocateAligned(const size_t items) { 207 | return AllocateAligned(items, nullptr, nullptr, nullptr); 208 | } 209 | 210 | } // namespace hwy 211 | #endif // HIGHWAY_HWY_ALIGNED_ALLOCATOR_H_ 212 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/RGBAlpha.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Radzivon Bartoshyk on 06/11/2023. 3 | // 4 | 5 | #include "RGBAlpha.h" 6 | 7 | using namespace std; 8 | 9 | #undef HWY_TARGET_INCLUDE 10 | #define HWY_TARGET_INCLUDE "RGBAlpha.cpp" 11 | 12 | #include "hwy/foreach_target.h" 13 | #include "hwy/highway.h" 14 | 15 | HWY_BEFORE_NAMESPACE(); 16 | 17 | namespace coder::HWY_NAMESPACE { 18 | 19 | using hwy::HWY_NAMESPACE::Vec; 20 | using hwy::HWY_NAMESPACE::FixedTag; 21 | using hwy::HWY_NAMESPACE::Min; 22 | using hwy::HWY_NAMESPACE::LoadInterleaved4; 23 | using hwy::HWY_NAMESPACE::StoreInterleaved4; 24 | using hwy::HWY_NAMESPACE::PromoteLowerTo; 25 | using hwy::HWY_NAMESPACE::PromoteUpperTo; 26 | using hwy::HWY_NAMESPACE::DemoteTo; 27 | using hwy::HWY_NAMESPACE::Combine; 28 | using hwy::HWY_NAMESPACE::Min; 29 | using hwy::HWY_NAMESPACE::Add; 30 | using hwy::HWY_NAMESPACE::Rebind; 31 | using hwy::HWY_NAMESPACE::Div; 32 | using hwy::HWY_NAMESPACE::ConvertTo; 33 | 34 | inline __attribute__((flatten)) Vec> 35 | RearrangeVec(Vec> vec) { 36 | const FixedTag du16x8; 37 | const FixedTag du16x4; 38 | const FixedTag du32x4; 39 | const FixedTag df32x4; 40 | Rebind ru32; 41 | using VU32x4 = Vec; 42 | const VU32x4 mult255 = Set(df32x4, 255); 43 | return Combine(du16x8, DemoteTo(du16x4, ConvertTo(ru32, Round(Div(ConvertTo(df32x4, 44 | PromoteUpperTo( 45 | du32x4, 46 | vec)), 47 | mult255)))), 48 | DemoteTo(du16x4, ConvertTo(ru32, Round(Div(ConvertTo(df32x4, 49 | PromoteLowerTo( 50 | du32x4, 51 | vec)), 52 | mult255))))); 53 | } 54 | 55 | void UnpremultiplyRGBA_HWY(const uint8_t *src, int srcStride, 56 | uint8_t *dst, int dstStride, int width, 57 | int height) { 58 | const FixedTag du8x16; 59 | const FixedTag du16x8; 60 | const FixedTag du8x8; 61 | 62 | using VU8x16 = Vec; 63 | using VU16x8 = Vec; 64 | 65 | VU16x8 mult255 = Set(du16x8, 255); 66 | 67 | for (int y = 0; y < height; ++y) { 68 | auto mSrc = reinterpret_cast(src + y * srcStride); 69 | auto mDst = reinterpret_cast(dst + y * dstStride); 70 | 71 | int x = 0; 72 | int pixels = 16; 73 | 74 | for (; x + pixels < width; x += pixels) { 75 | VU8x16 r8, g8, b8, a8; 76 | LoadInterleaved4(du8x16, mSrc, r8, g8, b8, a8); 77 | 78 | VU16x8 aLow = PromoteLowerTo(du16x8, a8); 79 | VU16x8 rLow = PromoteLowerTo(du16x8, r8); 80 | VU16x8 gLow = PromoteLowerTo(du16x8, g8); 81 | VU16x8 bLow = PromoteLowerTo(du16x8, b8); 82 | auto lowADivider = ShiftRight<1>(aLow); 83 | VU16x8 tmp = Add(Mul(Min(rLow, aLow), mult255), lowADivider); 84 | rLow = RearrangeVec(tmp); 85 | tmp = Add(Mul(Min(gLow, aLow), mult255), lowADivider); 86 | gLow = RearrangeVec(tmp); 87 | tmp = Add(Mul(Min(bLow, aLow), mult255), lowADivider); 88 | bLow = RearrangeVec(tmp); 89 | 90 | VU16x8 aHigh = PromoteUpperTo(du16x8, a8); 91 | VU16x8 rHigh = PromoteUpperTo(du16x8, r8); 92 | VU16x8 gHigh = PromoteUpperTo(du16x8, g8); 93 | VU16x8 bHigh = PromoteUpperTo(du16x8, b8); 94 | auto highADivider = ShiftRight<1>(aHigh); 95 | tmp = Add(Mul(Min(rHigh, aHigh), mult255), highADivider); 96 | rHigh = RearrangeVec(tmp); 97 | tmp = Add(Mul(Min(gHigh, aHigh), mult255), highADivider); 98 | gHigh = RearrangeVec(tmp); 99 | tmp = Add(Mul(Min(bHigh, aHigh), mult255), highADivider); 100 | bHigh = RearrangeVec(tmp); 101 | 102 | r8 = Combine(du8x16, DemoteTo(du8x8, rHigh), DemoteTo(du8x8, rLow)); 103 | g8 = Combine(du8x16, DemoteTo(du8x8, gHigh), DemoteTo(du8x8, gLow)); 104 | b8 = Combine(du8x16, DemoteTo(du8x8, bHigh), DemoteTo(du8x8, bLow)); 105 | 106 | StoreInterleaved4(r8, g8, b8, a8, du8x16, mDst); 107 | 108 | mSrc += pixels * 4; 109 | mDst += pixels * 4; 110 | } 111 | 112 | for (; x < width; ++x) { 113 | uint8_t alpha = mSrc[3]; 114 | mDst[0] = (min(mSrc[0], alpha) * 255 + alpha / 2) / alpha; 115 | mDst[1] = (min(mSrc[1], alpha) * 255 + alpha / 2) / alpha; 116 | mDst[2] = (min(mSrc[2], alpha) * 255 + alpha / 2) / alpha; 117 | mDst[3] = alpha; 118 | mSrc += 4; 119 | mDst += 4; 120 | } 121 | } 122 | } 123 | 124 | void PremultiplyRGBA_HWY(const uint8_t *src, int srcStride, 125 | uint8_t *dst, int dstStride, int width, 126 | int height) { 127 | const FixedTag du8x16; 128 | const FixedTag du16x8; 129 | const FixedTag du8x8; 130 | 131 | using VU8x16 = Vec; 132 | using VU16x8 = Vec; 133 | 134 | VU16x8 mult255d2 = Set(du16x8, 255 / 2); 135 | 136 | for (int y = 0; y < height; ++y) { 137 | auto mSrc = reinterpret_cast(src + y * srcStride); 138 | auto mDst = reinterpret_cast(dst + y * dstStride); 139 | 140 | int x = 0; 141 | int pixels = 16; 142 | 143 | for (; x + pixels < width; x += pixels) { 144 | VU8x16 r8, g8, b8, a8; 145 | LoadInterleaved4(du8x16, mSrc, r8, g8, b8, a8); 146 | 147 | VU16x8 aLow = PromoteLowerTo(du16x8, a8); 148 | VU16x8 rLow = PromoteLowerTo(du16x8, r8); 149 | VU16x8 gLow = PromoteLowerTo(du16x8, g8); 150 | VU16x8 bLow = PromoteLowerTo(du16x8, b8); 151 | VU16x8 tmp = Add(Mul(rLow, aLow), mult255d2); 152 | rLow = RearrangeVec(tmp); 153 | tmp = Add(Mul(gLow, aLow), mult255d2); 154 | gLow = RearrangeVec(tmp); 155 | tmp = Add(Mul(bLow, aLow), mult255d2); 156 | bLow = RearrangeVec(tmp); 157 | 158 | VU16x8 aHigh = PromoteUpperTo(du16x8, a8); 159 | VU16x8 rHigh = PromoteUpperTo(du16x8, r8); 160 | VU16x8 gHigh = PromoteUpperTo(du16x8, g8); 161 | VU16x8 bHigh = PromoteUpperTo(du16x8, b8); 162 | tmp = Add(Mul(rHigh, aHigh), mult255d2); 163 | rHigh = RearrangeVec(tmp); 164 | tmp = Add(Mul(gHigh, aHigh), mult255d2); 165 | gHigh = RearrangeVec(tmp); 166 | tmp = Add(Mul(bHigh, aHigh), mult255d2); 167 | bHigh = RearrangeVec(tmp); 168 | 169 | r8 = Combine(du8x16, DemoteTo(du8x8, rHigh), DemoteTo(du8x8, rLow)); 170 | g8 = Combine(du8x16, DemoteTo(du8x8, gHigh), DemoteTo(du8x8, gLow)); 171 | b8 = Combine(du8x16, DemoteTo(du8x8, bHigh), DemoteTo(du8x8, bLow)); 172 | 173 | StoreInterleaved4(r8, g8, b8, a8, du8x16, mDst); 174 | 175 | mSrc += pixels * 4; 176 | mDst += pixels * 4; 177 | } 178 | 179 | for (; x < width; ++x) { 180 | uint8_t alpha = mSrc[3]; 181 | mDst[0] = (mSrc[0] * alpha + 127) / 255; 182 | mDst[1] = (mSrc[1] * alpha + 127) / 255; 183 | mDst[2] = (mSrc[2] * alpha + 127) / 255; 184 | mDst[3] = alpha; 185 | mSrc += 4; 186 | mDst += 4; 187 | } 188 | } 189 | } 190 | } 191 | 192 | HWY_AFTER_NAMESPACE(); 193 | 194 | #if HWY_ONCE 195 | namespace coder { 196 | HWY_EXPORT(UnpremultiplyRGBA_HWY); 197 | HWY_EXPORT(PremultiplyRGBA_HWY); 198 | 199 | HWY_DLLEXPORT void UnpremultiplyRGBA(const uint8_t *src, int srcStride, 200 | uint8_t *dst, int dstStride, int width, 201 | int height) { 202 | HWY_DYNAMIC_DISPATCH(UnpremultiplyRGBA_HWY)(src, srcStride, dst, dstStride, width, height); 203 | } 204 | 205 | HWY_DLLEXPORT void PremultiplyRGBA(const uint8_t *src, int srcStride, 206 | uint8_t *dst, int dstStride, int width, 207 | int height) { 208 | HWY_DYNAMIC_DISPATCH(PremultiplyRGBA_HWY)(src, srcStride, dst, dstStride, width, height); 209 | } 210 | } 211 | #endif -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/video_common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | // Common definitions for video, including fourcc and VideoFormat. 12 | 13 | #ifndef INCLUDE_LIBYUV_VIDEO_COMMON_H_ 14 | #define INCLUDE_LIBYUV_VIDEO_COMMON_H_ 15 | 16 | #include "libyuv/basic_types.h" 17 | 18 | #ifdef __cplusplus 19 | namespace libyuv { 20 | extern "C" { 21 | #endif 22 | 23 | ////////////////////////////////////////////////////////////////////////////// 24 | // Definition of FourCC codes 25 | ////////////////////////////////////////////////////////////////////////////// 26 | 27 | // Convert four characters to a FourCC code. 28 | // Needs to be a macro otherwise the OS X compiler complains when the kFormat* 29 | // constants are used in a switch. 30 | #ifdef __cplusplus 31 | #define FOURCC(a, b, c, d) \ 32 | ((static_cast(a)) | (static_cast(b) << 8) | \ 33 | (static_cast(c) << 16) | /* NOLINT */ \ 34 | (static_cast(d) << 24)) /* NOLINT */ 35 | #else 36 | #define FOURCC(a, b, c, d) \ 37 | (((uint32_t)(a)) | ((uint32_t)(b) << 8) | /* NOLINT */ \ 38 | ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) /* NOLINT */ 39 | #endif 40 | 41 | // Some pages discussing FourCC codes: 42 | // http://www.fourcc.org/yuv.php 43 | // http://v4l2spec.bytesex.org/spec/book1.htm 44 | // http://developer.apple.com/quicktime/icefloe/dispatch020.html 45 | // http://msdn.microsoft.com/library/windows/desktop/dd206750.aspx#nv12 46 | // http://people.xiph.org/~xiphmont/containers/nut/nut4cc.txt 47 | 48 | // FourCC codes grouped according to implementation efficiency. 49 | // Primary formats should convert in 1 efficient step. 50 | // Secondary formats are converted in 2 steps. 51 | // Auxilliary formats call primary converters. 52 | enum FourCC { 53 | // 10 Primary YUV formats: 5 planar, 2 biplanar, 2 packed. 54 | FOURCC_I420 = FOURCC('I', '4', '2', '0'), 55 | FOURCC_I422 = FOURCC('I', '4', '2', '2'), 56 | FOURCC_I444 = FOURCC('I', '4', '4', '4'), 57 | FOURCC_I400 = FOURCC('I', '4', '0', '0'), 58 | FOURCC_NV21 = FOURCC('N', 'V', '2', '1'), 59 | FOURCC_NV12 = FOURCC('N', 'V', '1', '2'), 60 | FOURCC_YUY2 = FOURCC('Y', 'U', 'Y', '2'), 61 | FOURCC_UYVY = FOURCC('U', 'Y', 'V', 'Y'), 62 | FOURCC_I010 = FOURCC('I', '0', '1', '0'), // bt.601 10 bit 420 63 | FOURCC_I210 = FOURCC('I', '2', '1', '0'), // bt.601 10 bit 422 64 | 65 | // 1 Secondary YUV format: row biplanar. deprecated. 66 | FOURCC_M420 = FOURCC('M', '4', '2', '0'), 67 | 68 | // 13 Primary RGB formats: 4 32 bpp, 2 24 bpp, 3 16 bpp, 1 10 bpc 2 64 bpp 69 | FOURCC_ARGB = FOURCC('A', 'R', 'G', 'B'), 70 | FOURCC_BGRA = FOURCC('B', 'G', 'R', 'A'), 71 | FOURCC_ABGR = FOURCC('A', 'B', 'G', 'R'), 72 | FOURCC_AR30 = FOURCC('A', 'R', '3', '0'), // 10 bit per channel. 2101010. 73 | FOURCC_AB30 = FOURCC('A', 'B', '3', '0'), // ABGR version of 10 bit 74 | FOURCC_AR64 = FOURCC('A', 'R', '6', '4'), // 16 bit per channel. 75 | FOURCC_AB64 = FOURCC('A', 'B', '6', '4'), // ABGR version of 16 bit 76 | FOURCC_24BG = FOURCC('2', '4', 'B', 'G'), 77 | FOURCC_RAW = FOURCC('r', 'a', 'w', ' '), 78 | FOURCC_RGBA = FOURCC('R', 'G', 'B', 'A'), 79 | FOURCC_RGBP = FOURCC('R', 'G', 'B', 'P'), // rgb565 LE. 80 | FOURCC_RGBO = FOURCC('R', 'G', 'B', 'O'), // argb1555 LE. 81 | FOURCC_R444 = FOURCC('R', '4', '4', '4'), // argb4444 LE. 82 | 83 | // 1 Primary Compressed YUV format. 84 | FOURCC_MJPG = FOURCC('M', 'J', 'P', 'G'), 85 | 86 | // 14 Auxiliary YUV variations: 3 with U and V planes are swapped, 1 Alias. 87 | FOURCC_YV12 = FOURCC('Y', 'V', '1', '2'), 88 | FOURCC_YV16 = FOURCC('Y', 'V', '1', '6'), 89 | FOURCC_YV24 = FOURCC('Y', 'V', '2', '4'), 90 | FOURCC_YU12 = FOURCC('Y', 'U', '1', '2'), // Linux version of I420. 91 | FOURCC_J420 = 92 | FOURCC('J', '4', '2', '0'), // jpeg (bt.601 full), unofficial fourcc 93 | FOURCC_J422 = 94 | FOURCC('J', '4', '2', '2'), // jpeg (bt.601 full), unofficial fourcc 95 | FOURCC_J444 = 96 | FOURCC('J', '4', '4', '4'), // jpeg (bt.601 full), unofficial fourcc 97 | FOURCC_J400 = 98 | FOURCC('J', '4', '0', '0'), // jpeg (bt.601 full), unofficial fourcc 99 | FOURCC_F420 = FOURCC('F', '4', '2', '0'), // bt.709 full, unofficial fourcc 100 | FOURCC_F422 = FOURCC('F', '4', '2', '2'), // bt.709 full, unofficial fourcc 101 | FOURCC_F444 = FOURCC('F', '4', '4', '4'), // bt.709 full, unofficial fourcc 102 | FOURCC_H420 = FOURCC('H', '4', '2', '0'), // bt.709, unofficial fourcc 103 | FOURCC_H422 = FOURCC('H', '4', '2', '2'), // bt.709, unofficial fourcc 104 | FOURCC_H444 = FOURCC('H', '4', '4', '4'), // bt.709, unofficial fourcc 105 | FOURCC_U420 = FOURCC('U', '4', '2', '0'), // bt.2020, unofficial fourcc 106 | FOURCC_U422 = FOURCC('U', '4', '2', '2'), // bt.2020, unofficial fourcc 107 | FOURCC_U444 = FOURCC('U', '4', '4', '4'), // bt.2020, unofficial fourcc 108 | FOURCC_F010 = FOURCC('F', '0', '1', '0'), // bt.709 full range 10 bit 420 109 | FOURCC_H010 = FOURCC('H', '0', '1', '0'), // bt.709 10 bit 420 110 | FOURCC_U010 = FOURCC('U', '0', '1', '0'), // bt.2020 10 bit 420 111 | FOURCC_F210 = FOURCC('F', '2', '1', '0'), // bt.709 full range 10 bit 422 112 | FOURCC_H210 = FOURCC('H', '2', '1', '0'), // bt.709 10 bit 422 113 | FOURCC_U210 = FOURCC('U', '2', '1', '0'), // bt.2020 10 bit 422 114 | FOURCC_P010 = FOURCC('P', '0', '1', '0'), 115 | FOURCC_P210 = FOURCC('P', '2', '1', '0'), 116 | 117 | // 14 Auxiliary aliases. CanonicalFourCC() maps these to canonical fourcc. 118 | FOURCC_IYUV = FOURCC('I', 'Y', 'U', 'V'), // Alias for I420. 119 | FOURCC_YU16 = FOURCC('Y', 'U', '1', '6'), // Alias for I422. 120 | FOURCC_YU24 = FOURCC('Y', 'U', '2', '4'), // Alias for I444. 121 | FOURCC_YUYV = FOURCC('Y', 'U', 'Y', 'V'), // Alias for YUY2. 122 | FOURCC_YUVS = FOURCC('y', 'u', 'v', 's'), // Alias for YUY2 on Mac. 123 | FOURCC_HDYC = FOURCC('H', 'D', 'Y', 'C'), // Alias for UYVY. 124 | FOURCC_2VUY = FOURCC('2', 'v', 'u', 'y'), // Alias for UYVY on Mac. 125 | FOURCC_JPEG = FOURCC('J', 'P', 'E', 'G'), // Alias for MJPG. 126 | FOURCC_DMB1 = FOURCC('d', 'm', 'b', '1'), // Alias for MJPG on Mac. 127 | FOURCC_BA81 = FOURCC('B', 'A', '8', '1'), // Alias for BGGR. 128 | FOURCC_RGB3 = FOURCC('R', 'G', 'B', '3'), // Alias for RAW. 129 | FOURCC_BGR3 = FOURCC('B', 'G', 'R', '3'), // Alias for 24BG. 130 | FOURCC_CM32 = FOURCC(0, 0, 0, 32), // Alias for BGRA kCMPixelFormat_32ARGB 131 | FOURCC_CM24 = FOURCC(0, 0, 0, 24), // Alias for RAW kCMPixelFormat_24RGB 132 | FOURCC_L555 = FOURCC('L', '5', '5', '5'), // Alias for RGBO. 133 | FOURCC_L565 = FOURCC('L', '5', '6', '5'), // Alias for RGBP. 134 | FOURCC_5551 = FOURCC('5', '5', '5', '1'), // Alias for RGBO. 135 | 136 | // deprecated formats. Not supported, but defined for backward compatibility. 137 | FOURCC_I411 = FOURCC('I', '4', '1', '1'), 138 | FOURCC_Q420 = FOURCC('Q', '4', '2', '0'), 139 | FOURCC_RGGB = FOURCC('R', 'G', 'G', 'B'), 140 | FOURCC_BGGR = FOURCC('B', 'G', 'G', 'R'), 141 | FOURCC_GRBG = FOURCC('G', 'R', 'B', 'G'), 142 | FOURCC_GBRG = FOURCC('G', 'B', 'R', 'G'), 143 | FOURCC_H264 = FOURCC('H', '2', '6', '4'), 144 | 145 | // Match any fourcc. 146 | FOURCC_ANY = -1, 147 | }; 148 | 149 | enum FourCCBpp { 150 | // Canonical fourcc codes used in our code. 151 | FOURCC_BPP_I420 = 12, 152 | FOURCC_BPP_I422 = 16, 153 | FOURCC_BPP_I444 = 24, 154 | FOURCC_BPP_I411 = 12, 155 | FOURCC_BPP_I400 = 8, 156 | FOURCC_BPP_NV21 = 12, 157 | FOURCC_BPP_NV12 = 12, 158 | FOURCC_BPP_YUY2 = 16, 159 | FOURCC_BPP_UYVY = 16, 160 | FOURCC_BPP_M420 = 12, // deprecated 161 | FOURCC_BPP_Q420 = 12, 162 | FOURCC_BPP_ARGB = 32, 163 | FOURCC_BPP_BGRA = 32, 164 | FOURCC_BPP_ABGR = 32, 165 | FOURCC_BPP_RGBA = 32, 166 | FOURCC_BPP_AR30 = 32, 167 | FOURCC_BPP_AB30 = 32, 168 | FOURCC_BPP_AR64 = 64, 169 | FOURCC_BPP_AB64 = 64, 170 | FOURCC_BPP_24BG = 24, 171 | FOURCC_BPP_RAW = 24, 172 | FOURCC_BPP_RGBP = 16, 173 | FOURCC_BPP_RGBO = 16, 174 | FOURCC_BPP_R444 = 16, 175 | FOURCC_BPP_RGGB = 8, 176 | FOURCC_BPP_BGGR = 8, 177 | FOURCC_BPP_GRBG = 8, 178 | FOURCC_BPP_GBRG = 8, 179 | FOURCC_BPP_YV12 = 12, 180 | FOURCC_BPP_YV16 = 16, 181 | FOURCC_BPP_YV24 = 24, 182 | FOURCC_BPP_YU12 = 12, 183 | FOURCC_BPP_J420 = 12, 184 | FOURCC_BPP_J400 = 8, 185 | FOURCC_BPP_H420 = 12, 186 | FOURCC_BPP_H422 = 16, 187 | FOURCC_BPP_I010 = 15, 188 | FOURCC_BPP_I210 = 20, 189 | FOURCC_BPP_H010 = 15, 190 | FOURCC_BPP_H210 = 20, 191 | FOURCC_BPP_P010 = 15, 192 | FOURCC_BPP_P210 = 20, 193 | FOURCC_BPP_MJPG = 0, // 0 means unknown. 194 | FOURCC_BPP_H264 = 0, 195 | FOURCC_BPP_IYUV = 12, 196 | FOURCC_BPP_YU16 = 16, 197 | FOURCC_BPP_YU24 = 24, 198 | FOURCC_BPP_YUYV = 16, 199 | FOURCC_BPP_YUVS = 16, 200 | FOURCC_BPP_HDYC = 16, 201 | FOURCC_BPP_2VUY = 16, 202 | FOURCC_BPP_JPEG = 1, 203 | FOURCC_BPP_DMB1 = 1, 204 | FOURCC_BPP_BA81 = 8, 205 | FOURCC_BPP_RGB3 = 24, 206 | FOURCC_BPP_BGR3 = 24, 207 | FOURCC_BPP_CM32 = 32, 208 | FOURCC_BPP_CM24 = 24, 209 | 210 | // Match any fourcc. 211 | FOURCC_BPP_ANY = 0, // 0 means unknown. 212 | }; 213 | 214 | // Converts fourcc aliases into canonical ones. 215 | LIBYUV_API uint32_t CanonicalFourCC(uint32_t fourcc); 216 | 217 | #ifdef __cplusplus 218 | } // extern "C" 219 | } // namespace libyuv 220 | #endif 221 | 222 | #endif // INCLUDE_LIBYUV_VIDEO_COMMON_H_ 223 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/detect_compiler_arch.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_ 17 | #define HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_ 18 | 19 | // Detects compiler and arch from predefined macros. Zero dependencies for 20 | // inclusion by foreach_target.h. 21 | 22 | // Add to #if conditions to prevent IDE from graying out code. 23 | #if (defined __CDT_PARSER__) || (defined __INTELLISENSE__) || \ 24 | (defined Q_CREATOR_RUN) || (defined __CLANGD__) || \ 25 | (defined GROK_ELLIPSIS_BUILD) 26 | #define HWY_IDE 1 27 | #else 28 | #define HWY_IDE 0 29 | #endif 30 | 31 | //------------------------------------------------------------------------------ 32 | // Compiler 33 | 34 | // Actual MSVC, not clang-cl, which defines _MSC_VER but doesn't behave like 35 | // MSVC in other aspects (e.g. HWY_DIAGNOSTICS). 36 | #if defined(_MSC_VER) && !defined(__clang__) 37 | #define HWY_COMPILER_MSVC _MSC_VER 38 | #else 39 | #define HWY_COMPILER_MSVC 0 40 | #endif 41 | 42 | #if defined(_MSC_VER) && defined(__clang__) 43 | #define HWY_COMPILER_CLANGCL _MSC_VER 44 | #else 45 | #define HWY_COMPILER_CLANGCL 0 46 | #endif 47 | 48 | #ifdef __INTEL_COMPILER 49 | #define HWY_COMPILER_ICC __INTEL_COMPILER 50 | #else 51 | #define HWY_COMPILER_ICC 0 52 | #endif 53 | 54 | #ifdef __INTEL_LLVM_COMPILER 55 | #define HWY_COMPILER_ICX __INTEL_LLVM_COMPILER 56 | #else 57 | #define HWY_COMPILER_ICX 0 58 | #endif 59 | 60 | // HWY_COMPILER_GCC is a generic macro for all compilers implementing the GNU 61 | // compiler extensions (eg. Clang, Intel...) 62 | #ifdef __GNUC__ 63 | #define HWY_COMPILER_GCC (__GNUC__ * 100 + __GNUC_MINOR__) 64 | #else 65 | #define HWY_COMPILER_GCC 0 66 | #endif 67 | 68 | // Clang or clang-cl, not GCC. 69 | #ifdef __clang__ 70 | // In case of Apple LLVM (whose version number is unrelated to that of LLVM) or 71 | // an invalid version number, deduce it from the presence of warnings. 72 | // Originally based on 73 | // https://github.com/simd-everywhere/simde/blob/47d6e603de9d04ee05cdfbc57cf282a02be1bf2a/simde/simde-detect-clang.h#L59. 74 | // Please send updates below to them as well, thanks! 75 | #if defined(__apple_build_version__) || __clang_major__ >= 999 76 | #if __has_attribute(nouwtable) // no new warnings in 16.0 77 | #define HWY_COMPILER_CLANG 1600 78 | #elif __has_warning("-Warray-parameter") 79 | #define HWY_COMPILER_CLANG 1500 80 | #elif __has_warning("-Wbitwise-instead-of-logical") 81 | #define HWY_COMPILER_CLANG 1400 82 | #elif __has_warning("-Wreserved-identifier") 83 | #define HWY_COMPILER_CLANG 1300 84 | #elif __has_warning("-Wformat-insufficient-args") 85 | #define HWY_COMPILER_CLANG 1200 86 | #elif __has_warning("-Wimplicit-const-int-float-conversion") 87 | #define HWY_COMPILER_CLANG 1100 88 | #elif __has_warning("-Wmisleading-indentation") 89 | #define HWY_COMPILER_CLANG 1000 90 | #elif defined(__FILE_NAME__) 91 | #define HWY_COMPILER_CLANG 900 92 | #elif __has_warning("-Wextra-semi-stmt") || \ 93 | __has_builtin(__builtin_rotateleft32) 94 | #define HWY_COMPILER_CLANG 800 95 | // For reasons unknown, XCode 10.3 (Apple LLVM version 10.0.1) is apparently 96 | // based on Clang 7, but does not support the warning we test. 97 | // See https://en.wikipedia.org/wiki/Xcode#Toolchain_versions and 98 | // https://trac.macports.org/wiki/XcodeVersionInfo. 99 | #elif __has_warning("-Wc++98-compat-extra-semi") || \ 100 | (defined(__apple_build_version__) && __apple_build_version__ >= 10010000) 101 | #define HWY_COMPILER_CLANG 700 102 | #else // Anything older than 7.0 is not recommended for Highway. 103 | #define HWY_COMPILER_CLANG 600 104 | #endif // __has_warning chain 105 | #define HWY_COMPILER3_CLANG (HWY_COMPILER_CLANG * 100) 106 | #else // use normal version 107 | #define HWY_COMPILER_CLANG (__clang_major__ * 100 + __clang_minor__) 108 | #define HWY_COMPILER3_CLANG \ 109 | (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) 110 | #endif 111 | #else // Not clang 112 | #define HWY_COMPILER_CLANG 0 113 | #define HWY_COMPILER3_CLANG 0 114 | #endif 115 | 116 | #if HWY_COMPILER_GCC && !HWY_COMPILER_CLANG && !HWY_COMPILER_ICC 117 | #define HWY_COMPILER_GCC_ACTUAL HWY_COMPILER_GCC 118 | #else 119 | #define HWY_COMPILER_GCC_ACTUAL 0 120 | #endif 121 | 122 | // More than one may be nonzero, but we want at least one. 123 | #if 0 == (HWY_COMPILER_MSVC + HWY_COMPILER_CLANGCL + HWY_COMPILER_ICC + \ 124 | HWY_COMPILER_GCC + HWY_COMPILER_CLANG) 125 | #error "Unsupported compiler" 126 | #endif 127 | 128 | // We should only detect one of these (only clang/clangcl overlap) 129 | #if 1 < \ 130 | (!!HWY_COMPILER_MSVC + !!HWY_COMPILER_ICC + !!HWY_COMPILER_GCC_ACTUAL + \ 131 | !!(HWY_COMPILER_CLANGCL | HWY_COMPILER_CLANG)) 132 | #error "Detected multiple compilers" 133 | #endif 134 | 135 | #ifdef __has_builtin 136 | #define HWY_HAS_BUILTIN(name) __has_builtin(name) 137 | #else 138 | #define HWY_HAS_BUILTIN(name) 0 139 | #endif 140 | 141 | #ifdef __has_attribute 142 | #define HWY_HAS_ATTRIBUTE(name) __has_attribute(name) 143 | #else 144 | #define HWY_HAS_ATTRIBUTE(name) 0 145 | #endif 146 | 147 | #ifdef __has_cpp_attribute 148 | #define HWY_HAS_CPP_ATTRIBUTE(name) __has_cpp_attribute(name) 149 | #else 150 | #define HWY_HAS_CPP_ATTRIBUTE(name) 0 151 | #endif 152 | 153 | #ifdef __has_feature 154 | #define HWY_HAS_FEATURE(name) __has_feature(name) 155 | #else 156 | #define HWY_HAS_FEATURE(name) 0 157 | #endif 158 | 159 | //------------------------------------------------------------------------------ 160 | // Architecture 161 | 162 | #if defined(__i386__) || defined(_M_IX86) 163 | #define HWY_ARCH_X86_32 1 164 | #else 165 | #define HWY_ARCH_X86_32 0 166 | #endif 167 | 168 | #if defined(__x86_64__) || defined(_M_X64) 169 | #define HWY_ARCH_X86_64 1 170 | #else 171 | #define HWY_ARCH_X86_64 0 172 | #endif 173 | 174 | #if HWY_ARCH_X86_32 && HWY_ARCH_X86_64 175 | #error "Cannot have both x86-32 and x86-64" 176 | #endif 177 | 178 | #if HWY_ARCH_X86_32 || HWY_ARCH_X86_64 179 | #define HWY_ARCH_X86 1 180 | #else 181 | #define HWY_ARCH_X86 0 182 | #endif 183 | 184 | #if defined(__powerpc64__) || defined(_M_PPC) || defined(__powerpc__) 185 | #define HWY_ARCH_PPC 1 186 | #else 187 | #define HWY_ARCH_PPC 0 188 | #endif 189 | 190 | // aarch32 is currently not supported; please raise an issue if you want it. 191 | #if defined(__ARM_ARCH_ISA_A64) || defined(__aarch64__) || defined(_M_ARM64) 192 | #define HWY_ARCH_ARM_A64 1 193 | #else 194 | #define HWY_ARCH_ARM_A64 0 195 | #endif 196 | 197 | #if (defined(__ARM_ARCH) && __ARM_ARCH == 7) || (defined(_M_ARM) && _M_ARM == 7) 198 | #define HWY_ARCH_ARM_V7 1 199 | #else 200 | #define HWY_ARCH_ARM_V7 0 201 | #endif 202 | 203 | #if HWY_ARCH_ARM_A64 && HWY_ARCH_ARM_V7 204 | #error "Cannot have both A64 and V7" 205 | #endif 206 | 207 | // Any *supported* version of Arm, i.e. 7 or later 208 | #if HWY_ARCH_ARM_A64 || HWY_ARCH_ARM_V7 209 | #define HWY_ARCH_ARM 1 210 | #else 211 | #define HWY_ARCH_ARM 0 212 | #endif 213 | 214 | // Older than Armv7 (e.g. armel aka Armv5) => we do not support SIMD. 215 | #if (defined(__arm__) || defined(_M_ARM)) && !HWY_ARCH_ARM 216 | #define HWY_ARCH_ARM_OLD 1 217 | #else 218 | #define HWY_ARCH_ARM_OLD 0 219 | #endif 220 | 221 | #if defined(__EMSCRIPTEN__) || defined(__wasm__) || defined(__WASM__) 222 | #define HWY_ARCH_WASM 1 223 | #else 224 | #define HWY_ARCH_WASM 0 225 | #endif 226 | 227 | #ifdef __riscv 228 | #define HWY_ARCH_RVV 1 229 | #else 230 | #define HWY_ARCH_RVV 0 231 | #endif 232 | 233 | // It is an error to detect multiple architectures at the same time, but OK to 234 | // detect none of the above. 235 | #if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_ARM_OLD + \ 236 | HWY_ARCH_WASM + HWY_ARCH_RVV) > 1 237 | #error "Must not detect more than one architecture" 238 | #endif 239 | 240 | #if defined(_WIN32) || defined(_WIN64) 241 | #define HWY_OS_WIN 1 242 | #else 243 | #define HWY_OS_WIN 0 244 | #endif 245 | 246 | #if defined(linux) || defined(__linux__) 247 | #define HWY_OS_LINUX 1 248 | #else 249 | #define HWY_OS_LINUX 0 250 | #endif 251 | 252 | //------------------------------------------------------------------------------ 253 | // Endianness 254 | 255 | #if HWY_COMPILER_MSVC 256 | #if HWY_ARCH_PPC && defined(_XBOX_VER) && _XBOX_VER >= 200 257 | // XBox 360 is big-endian 258 | #define HWY_IS_LITTLE_ENDIAN 0 259 | #define HWY_IS_BIG_ENDIAN 1 260 | #else 261 | // All other targets supported by MSVC are little-endian 262 | #define HWY_IS_LITTLE_ENDIAN 1 263 | #define HWY_IS_BIG_ENDIAN 0 264 | #endif // HWY_ARCH_PPC && defined(_XBOX_VER) && _XBOX_VER >= 200 265 | #elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ 266 | __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 267 | #define HWY_IS_LITTLE_ENDIAN 1 268 | #define HWY_IS_BIG_ENDIAN 0 269 | #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ 270 | __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 271 | #define HWY_IS_LITTLE_ENDIAN 0 272 | #define HWY_IS_BIG_ENDIAN 1 273 | #else 274 | #error "Unable to detect endianness or unsupported byte order" 275 | #endif 276 | 277 | #if (HWY_IS_LITTLE_ENDIAN + HWY_IS_BIG_ENDIAN) != 1 278 | #error "Must only detect one byte order" 279 | #endif 280 | 281 | #endif // HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_ 282 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/hwy/foreach_target.h: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Google LLC 2 | // SPDX-License-Identifier: Apache-2.0 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | #ifndef HIGHWAY_HWY_FOREACH_TARGET_H_ 17 | #define HIGHWAY_HWY_FOREACH_TARGET_H_ 18 | 19 | // Re-includes the translation unit zero or more times to compile for any 20 | // targets except HWY_STATIC_TARGET. Defines unique HWY_TARGET each time so that 21 | // highway.h defines the corresponding macro/namespace. 22 | 23 | #include "hwy/detect_targets.h" 24 | 25 | // *_inl.h may include other headers, which requires include guards to prevent 26 | // repeated inclusion. The guards must be reset after compiling each target, so 27 | // the header is again visible. This is done by flipping HWY_TARGET_TOGGLE, 28 | // defining it if undefined and vice versa. This macro is initially undefined 29 | // so that IDEs don't gray out the contents of each header. 30 | #ifdef HWY_TARGET_TOGGLE 31 | #error "This macro must not be defined outside foreach_target.h" 32 | #endif 33 | 34 | #ifdef HWY_HIGHWAY_INCLUDED // highway.h include guard 35 | // Trigger fixup at the bottom of this header. 36 | #define HWY_ALREADY_INCLUDED 37 | 38 | // The next highway.h must re-include set_macros-inl.h because the first 39 | // highway.h chose the static target instead of what we will set below. 40 | #undef HWY_SET_MACROS_PER_TARGET 41 | #endif 42 | 43 | // Disable HWY_EXPORT in user code until we have generated all targets. Note 44 | // that a subsequent highway.h will not override this definition. 45 | #undef HWY_ONCE 46 | #define HWY_ONCE (0 || HWY_IDE) 47 | 48 | // Avoid warnings on #include HWY_TARGET_INCLUDE by hiding them from the IDE; 49 | // also skip if only 1 target defined (no re-inclusion will be necessary). 50 | #if !HWY_IDE && (HWY_TARGETS != HWY_STATIC_TARGET) 51 | 52 | #if !defined(HWY_TARGET_INCLUDE) 53 | #error ">1 target enabled => define HWY_TARGET_INCLUDE before foreach_target.h" 54 | #endif 55 | 56 | // ------------------------------ HWY_ARCH_X86 57 | 58 | #if (HWY_TARGETS & HWY_SSE2) && (HWY_STATIC_TARGET != HWY_SSE2) 59 | #undef HWY_TARGET 60 | #define HWY_TARGET HWY_SSE2 61 | #include HWY_TARGET_INCLUDE 62 | #ifdef HWY_TARGET_TOGGLE 63 | #undef HWY_TARGET_TOGGLE 64 | #else 65 | #define HWY_TARGET_TOGGLE 66 | #endif 67 | #endif 68 | 69 | #if (HWY_TARGETS & HWY_SSSE3) && (HWY_STATIC_TARGET != HWY_SSSE3) 70 | #undef HWY_TARGET 71 | #define HWY_TARGET HWY_SSSE3 72 | #include HWY_TARGET_INCLUDE 73 | #ifdef HWY_TARGET_TOGGLE 74 | #undef HWY_TARGET_TOGGLE 75 | #else 76 | #define HWY_TARGET_TOGGLE 77 | #endif 78 | #endif 79 | 80 | #if (HWY_TARGETS & HWY_SSE4) && (HWY_STATIC_TARGET != HWY_SSE4) 81 | #undef HWY_TARGET 82 | #define HWY_TARGET HWY_SSE4 83 | #include HWY_TARGET_INCLUDE 84 | #ifdef HWY_TARGET_TOGGLE 85 | #undef HWY_TARGET_TOGGLE 86 | #else 87 | #define HWY_TARGET_TOGGLE 88 | #endif 89 | #endif 90 | 91 | #if (HWY_TARGETS & HWY_AVX2) && (HWY_STATIC_TARGET != HWY_AVX2) 92 | #undef HWY_TARGET 93 | #define HWY_TARGET HWY_AVX2 94 | #include HWY_TARGET_INCLUDE 95 | #ifdef HWY_TARGET_TOGGLE 96 | #undef HWY_TARGET_TOGGLE 97 | #else 98 | #define HWY_TARGET_TOGGLE 99 | #endif 100 | #endif 101 | 102 | #if (HWY_TARGETS & HWY_AVX3) && (HWY_STATIC_TARGET != HWY_AVX3) 103 | #undef HWY_TARGET 104 | #define HWY_TARGET HWY_AVX3 105 | #include HWY_TARGET_INCLUDE 106 | #ifdef HWY_TARGET_TOGGLE 107 | #undef HWY_TARGET_TOGGLE 108 | #else 109 | #define HWY_TARGET_TOGGLE 110 | #endif 111 | #endif 112 | 113 | #if (HWY_TARGETS & HWY_AVX3_DL) && (HWY_STATIC_TARGET != HWY_AVX3_DL) 114 | #undef HWY_TARGET 115 | #define HWY_TARGET HWY_AVX3_DL 116 | #include HWY_TARGET_INCLUDE 117 | #ifdef HWY_TARGET_TOGGLE 118 | #undef HWY_TARGET_TOGGLE 119 | #else 120 | #define HWY_TARGET_TOGGLE 121 | #endif 122 | #endif 123 | 124 | #if (HWY_TARGETS & HWY_AVX3_ZEN4) && (HWY_STATIC_TARGET != HWY_AVX3_ZEN4) 125 | #undef HWY_TARGET 126 | #define HWY_TARGET HWY_AVX3_ZEN4 127 | #include HWY_TARGET_INCLUDE 128 | #ifdef HWY_TARGET_TOGGLE 129 | #undef HWY_TARGET_TOGGLE 130 | #else 131 | #define HWY_TARGET_TOGGLE 132 | #endif 133 | #endif 134 | 135 | #if (HWY_TARGETS & HWY_AVX3_SPR) && (HWY_STATIC_TARGET != HWY_AVX3_SPR) 136 | #undef HWY_TARGET 137 | #define HWY_TARGET HWY_AVX3_SPR 138 | #include HWY_TARGET_INCLUDE 139 | #ifdef HWY_TARGET_TOGGLE 140 | #undef HWY_TARGET_TOGGLE 141 | #else 142 | #define HWY_TARGET_TOGGLE 143 | #endif 144 | #endif 145 | 146 | // ------------------------------ HWY_ARCH_ARM 147 | 148 | #if (HWY_TARGETS & HWY_NEON_WITHOUT_AES) && \ 149 | (HWY_STATIC_TARGET != HWY_NEON_WITHOUT_AES) 150 | #undef HWY_TARGET 151 | #define HWY_TARGET HWY_NEON_WITHOUT_AES 152 | #include HWY_TARGET_INCLUDE 153 | #ifdef HWY_TARGET_TOGGLE 154 | #undef HWY_TARGET_TOGGLE 155 | #else 156 | #define HWY_TARGET_TOGGLE 157 | #endif 158 | #endif 159 | 160 | #if (HWY_TARGETS & HWY_NEON) && (HWY_STATIC_TARGET != HWY_NEON) 161 | #undef HWY_TARGET 162 | #define HWY_TARGET HWY_NEON 163 | #include HWY_TARGET_INCLUDE 164 | #ifdef HWY_TARGET_TOGGLE 165 | #undef HWY_TARGET_TOGGLE 166 | #else 167 | #define HWY_TARGET_TOGGLE 168 | #endif 169 | #endif 170 | 171 | #if (HWY_TARGETS & HWY_SVE) && (HWY_STATIC_TARGET != HWY_SVE) 172 | #undef HWY_TARGET 173 | #define HWY_TARGET HWY_SVE 174 | #include HWY_TARGET_INCLUDE 175 | #ifdef HWY_TARGET_TOGGLE 176 | #undef HWY_TARGET_TOGGLE 177 | #else 178 | #define HWY_TARGET_TOGGLE 179 | #endif 180 | #endif 181 | 182 | #if (HWY_TARGETS & HWY_SVE2) && (HWY_STATIC_TARGET != HWY_SVE2) 183 | #undef HWY_TARGET 184 | #define HWY_TARGET HWY_SVE2 185 | #include HWY_TARGET_INCLUDE 186 | #ifdef HWY_TARGET_TOGGLE 187 | #undef HWY_TARGET_TOGGLE 188 | #else 189 | #define HWY_TARGET_TOGGLE 190 | #endif 191 | #endif 192 | 193 | #if (HWY_TARGETS & HWY_SVE_256) && (HWY_STATIC_TARGET != HWY_SVE_256) 194 | #undef HWY_TARGET 195 | #define HWY_TARGET HWY_SVE_256 196 | #include HWY_TARGET_INCLUDE 197 | #ifdef HWY_TARGET_TOGGLE 198 | #undef HWY_TARGET_TOGGLE 199 | #else 200 | #define HWY_TARGET_TOGGLE 201 | #endif 202 | #endif 203 | 204 | #if (HWY_TARGETS & HWY_SVE2_128) && (HWY_STATIC_TARGET != HWY_SVE2_128) 205 | #undef HWY_TARGET 206 | #define HWY_TARGET HWY_SVE2_128 207 | #include HWY_TARGET_INCLUDE 208 | #ifdef HWY_TARGET_TOGGLE 209 | #undef HWY_TARGET_TOGGLE 210 | #else 211 | #define HWY_TARGET_TOGGLE 212 | #endif 213 | #endif 214 | 215 | // ------------------------------ HWY_ARCH_WASM 216 | 217 | #if (HWY_TARGETS & HWY_WASM_EMU256) && (HWY_STATIC_TARGET != HWY_WASM_EMU256) 218 | #undef HWY_TARGET 219 | #define HWY_TARGET HWY_WASM_EMU256 220 | #include HWY_TARGET_INCLUDE 221 | #ifdef HWY_TARGET_TOGGLE 222 | #undef HWY_TARGET_TOGGLE 223 | #else 224 | #define HWY_TARGET_TOGGLE 225 | #endif 226 | #endif 227 | 228 | #if (HWY_TARGETS & HWY_WASM) && (HWY_STATIC_TARGET != HWY_WASM) 229 | #undef HWY_TARGET 230 | #define HWY_TARGET HWY_WASM 231 | #include HWY_TARGET_INCLUDE 232 | #ifdef HWY_TARGET_TOGGLE 233 | #undef HWY_TARGET_TOGGLE 234 | #else 235 | #define HWY_TARGET_TOGGLE 236 | #endif 237 | #endif 238 | 239 | // ------------------------------ HWY_ARCH_PPC 240 | 241 | #if (HWY_TARGETS & HWY_PPC8) && (HWY_STATIC_TARGET != HWY_PPC8) 242 | #undef HWY_TARGET 243 | #define HWY_TARGET HWY_PPC8 244 | #include HWY_TARGET_INCLUDE 245 | #ifdef HWY_TARGET_TOGGLE 246 | #undef HWY_TARGET_TOGGLE 247 | #else 248 | #define HWY_TARGET_TOGGLE 249 | #endif 250 | #endif 251 | 252 | #if (HWY_TARGETS & HWY_PPC9) && (HWY_STATIC_TARGET != HWY_PPC9) 253 | #undef HWY_TARGET 254 | #define HWY_TARGET HWY_PPC9 255 | #include HWY_TARGET_INCLUDE 256 | #ifdef HWY_TARGET_TOGGLE 257 | #undef HWY_TARGET_TOGGLE 258 | #else 259 | #define HWY_TARGET_TOGGLE 260 | #endif 261 | #endif 262 | 263 | #if (HWY_TARGETS & HWY_PPC10) && (HWY_STATIC_TARGET != HWY_PPC10) 264 | #undef HWY_TARGET 265 | #define HWY_TARGET HWY_PPC10 266 | #include HWY_TARGET_INCLUDE 267 | #ifdef HWY_TARGET_TOGGLE 268 | #undef HWY_TARGET_TOGGLE 269 | #else 270 | #define HWY_TARGET_TOGGLE 271 | #endif 272 | #endif 273 | 274 | // ------------------------------ HWY_ARCH_RVV 275 | 276 | #if (HWY_TARGETS & HWY_RVV) && (HWY_STATIC_TARGET != HWY_RVV) 277 | #undef HWY_TARGET 278 | #define HWY_TARGET HWY_RVV 279 | #include HWY_TARGET_INCLUDE 280 | #ifdef HWY_TARGET_TOGGLE 281 | #undef HWY_TARGET_TOGGLE 282 | #else 283 | #define HWY_TARGET_TOGGLE 284 | #endif 285 | #endif 286 | 287 | // ------------------------------ Scalar 288 | 289 | #if (HWY_TARGETS & HWY_EMU128) && (HWY_STATIC_TARGET != HWY_EMU128) 290 | #undef HWY_TARGET 291 | #define HWY_TARGET HWY_EMU128 292 | #include HWY_TARGET_INCLUDE 293 | #ifdef HWY_TARGET_TOGGLE 294 | #undef HWY_TARGET_TOGGLE 295 | #else 296 | #define HWY_TARGET_TOGGLE 297 | #endif 298 | #endif 299 | 300 | #if (HWY_TARGETS & HWY_SCALAR) && (HWY_STATIC_TARGET != HWY_SCALAR) 301 | #undef HWY_TARGET 302 | #define HWY_TARGET HWY_SCALAR 303 | #include HWY_TARGET_INCLUDE 304 | #ifdef HWY_TARGET_TOGGLE 305 | #undef HWY_TARGET_TOGGLE 306 | #else 307 | #define HWY_TARGET_TOGGLE 308 | #endif 309 | #endif 310 | 311 | #endif // !HWY_IDE && (HWY_TARGETS != HWY_STATIC_TARGET) 312 | 313 | // Now that all but the static target have been generated, re-enable HWY_EXPORT. 314 | #undef HWY_ONCE 315 | #define HWY_ONCE 1 316 | 317 | // If we re-include once per enabled target, the translation unit's 318 | // implementation would have to be skipped via #if to avoid redefining symbols. 319 | // We instead skip the re-include for HWY_STATIC_TARGET, and generate its 320 | // implementation when resuming compilation of the translation unit. 321 | #undef HWY_TARGET 322 | #define HWY_TARGET HWY_STATIC_TARGET 323 | 324 | #ifdef HWY_ALREADY_INCLUDED 325 | // Revert the previous toggle to prevent redefinitions for the static target. 326 | #ifdef HWY_TARGET_TOGGLE 327 | #undef HWY_TARGET_TOGGLE 328 | #else 329 | #define HWY_TARGET_TOGGLE 330 | #endif 331 | 332 | // Force re-inclusion of set_macros-inl.h now that HWY_TARGET is restored. 333 | #ifdef HWY_SET_MACROS_PER_TARGET 334 | #undef HWY_SET_MACROS_PER_TARGET 335 | #else 336 | #define HWY_SET_MACROS_PER_TARGET 337 | #endif 338 | #endif 339 | 340 | #endif // HIGHWAY_HWY_FOREACH_TARGET_H_ 341 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/convert_from_argb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ 12 | #define INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | // Copy ARGB to ARGB. 22 | #define ARGBToARGB ARGBCopy 23 | LIBYUV_API 24 | int ARGBCopy(const uint8_t* src_argb, 25 | int src_stride_argb, 26 | uint8_t* dst_argb, 27 | int dst_stride_argb, 28 | int width, 29 | int height); 30 | 31 | // Convert ARGB To BGRA. 32 | LIBYUV_API 33 | int ARGBToBGRA(const uint8_t* src_argb, 34 | int src_stride_argb, 35 | uint8_t* dst_bgra, 36 | int dst_stride_bgra, 37 | int width, 38 | int height); 39 | 40 | // Convert ARGB To ABGR. 41 | LIBYUV_API 42 | int ARGBToABGR(const uint8_t* src_argb, 43 | int src_stride_argb, 44 | uint8_t* dst_abgr, 45 | int dst_stride_abgr, 46 | int width, 47 | int height); 48 | 49 | // Convert ARGB To RGBA. 50 | LIBYUV_API 51 | int ARGBToRGBA(const uint8_t* src_argb, 52 | int src_stride_argb, 53 | uint8_t* dst_rgba, 54 | int dst_stride_rgba, 55 | int width, 56 | int height); 57 | 58 | // Aliases 59 | #define ARGBToAB30 ABGRToAR30 60 | #define ABGRToAB30 ARGBToAR30 61 | 62 | // Convert ABGR To AR30. 63 | LIBYUV_API 64 | int ABGRToAR30(const uint8_t* src_abgr, 65 | int src_stride_abgr, 66 | uint8_t* dst_ar30, 67 | int dst_stride_ar30, 68 | int width, 69 | int height); 70 | 71 | // Convert ARGB To AR30. 72 | LIBYUV_API 73 | int ARGBToAR30(const uint8_t* src_argb, 74 | int src_stride_argb, 75 | uint8_t* dst_ar30, 76 | int dst_stride_ar30, 77 | int width, 78 | int height); 79 | 80 | // Aliases 81 | #define ABGRToRGB24 ARGBToRAW 82 | #define ABGRToRAW ARGBToRGB24 83 | 84 | // Convert ARGB To RGB24. 85 | LIBYUV_API 86 | int ARGBToRGB24(const uint8_t* src_argb, 87 | int src_stride_argb, 88 | uint8_t* dst_rgb24, 89 | int dst_stride_rgb24, 90 | int width, 91 | int height); 92 | 93 | // Convert ARGB To RAW. 94 | LIBYUV_API 95 | int ARGBToRAW(const uint8_t* src_argb, 96 | int src_stride_argb, 97 | uint8_t* dst_raw, 98 | int dst_stride_raw, 99 | int width, 100 | int height); 101 | 102 | // Convert ARGB To RGB565. 103 | LIBYUV_API 104 | int ARGBToRGB565(const uint8_t* src_argb, 105 | int src_stride_argb, 106 | uint8_t* dst_rgb565, 107 | int dst_stride_rgb565, 108 | int width, 109 | int height); 110 | 111 | // Convert ARGB To RGB565 with 4x4 dither matrix (16 bytes). 112 | // Values in dither matrix from 0 to 7 recommended. 113 | // The order of the dither matrix is first byte is upper left. 114 | // TODO(fbarchard): Consider pointer to 2d array for dither4x4. 115 | // const uint8_t(*dither)[4][4]; 116 | LIBYUV_API 117 | int ARGBToRGB565Dither(const uint8_t* src_argb, 118 | int src_stride_argb, 119 | uint8_t* dst_rgb565, 120 | int dst_stride_rgb565, 121 | const uint8_t* dither4x4, 122 | int width, 123 | int height); 124 | 125 | // Convert ARGB To ARGB1555. 126 | LIBYUV_API 127 | int ARGBToARGB1555(const uint8_t* src_argb, 128 | int src_stride_argb, 129 | uint8_t* dst_argb1555, 130 | int dst_stride_argb1555, 131 | int width, 132 | int height); 133 | 134 | // Convert ARGB To ARGB4444. 135 | LIBYUV_API 136 | int ARGBToARGB4444(const uint8_t* src_argb, 137 | int src_stride_argb, 138 | uint8_t* dst_argb4444, 139 | int dst_stride_argb4444, 140 | int width, 141 | int height); 142 | 143 | // Convert ARGB To I444. 144 | LIBYUV_API 145 | int ARGBToI444(const uint8_t* src_argb, 146 | int src_stride_argb, 147 | uint8_t* dst_y, 148 | int dst_stride_y, 149 | uint8_t* dst_u, 150 | int dst_stride_u, 151 | uint8_t* dst_v, 152 | int dst_stride_v, 153 | int width, 154 | int height); 155 | 156 | // Convert ARGB to AR64. 157 | LIBYUV_API 158 | int ARGBToAR64(const uint8_t* src_argb, 159 | int src_stride_argb, 160 | uint16_t* dst_ar64, 161 | int dst_stride_ar64, 162 | int width, 163 | int height); 164 | 165 | // Convert ABGR to AB64. 166 | #define ABGRToAB64 ARGBToAR64 167 | 168 | // Convert ARGB to AB64. 169 | LIBYUV_API 170 | int ARGBToAB64(const uint8_t* src_argb, 171 | int src_stride_argb, 172 | uint16_t* dst_ab64, 173 | int dst_stride_ab64, 174 | int width, 175 | int height); 176 | 177 | // Convert ABGR to AR64. 178 | #define ABGRToAR64 ARGBToAB64 179 | 180 | // Convert ARGB To I422. 181 | LIBYUV_API 182 | int ARGBToI422(const uint8_t* src_argb, 183 | int src_stride_argb, 184 | uint8_t* dst_y, 185 | int dst_stride_y, 186 | uint8_t* dst_u, 187 | int dst_stride_u, 188 | uint8_t* dst_v, 189 | int dst_stride_v, 190 | int width, 191 | int height); 192 | 193 | // Convert ARGB To I420. (also in convert.h) 194 | LIBYUV_API 195 | int ARGBToI420(const uint8_t* src_argb, 196 | int src_stride_argb, 197 | uint8_t* dst_y, 198 | int dst_stride_y, 199 | uint8_t* dst_u, 200 | int dst_stride_u, 201 | uint8_t* dst_v, 202 | int dst_stride_v, 203 | int width, 204 | int height); 205 | 206 | // Convert ARGB to J420. (JPeg full range I420). 207 | LIBYUV_API 208 | int ARGBToJ420(const uint8_t* src_argb, 209 | int src_stride_argb, 210 | uint8_t* dst_yj, 211 | int dst_stride_yj, 212 | uint8_t* dst_u, 213 | int dst_stride_u, 214 | uint8_t* dst_v, 215 | int dst_stride_v, 216 | int width, 217 | int height); 218 | 219 | // Convert ARGB to J422. 220 | LIBYUV_API 221 | int ARGBToJ422(const uint8_t* src_argb, 222 | int src_stride_argb, 223 | uint8_t* dst_yj, 224 | int dst_stride_yj, 225 | uint8_t* dst_u, 226 | int dst_stride_u, 227 | uint8_t* dst_v, 228 | int dst_stride_v, 229 | int width, 230 | int height); 231 | 232 | // Convert ARGB to J400. (JPeg full range). 233 | LIBYUV_API 234 | int ARGBToJ400(const uint8_t* src_argb, 235 | int src_stride_argb, 236 | uint8_t* dst_yj, 237 | int dst_stride_yj, 238 | int width, 239 | int height); 240 | 241 | // Convert RGBA to J400. (JPeg full range). 242 | LIBYUV_API 243 | int RGBAToJ400(const uint8_t* src_rgba, 244 | int src_stride_rgba, 245 | uint8_t* dst_yj, 246 | int dst_stride_yj, 247 | int width, 248 | int height); 249 | 250 | // Convert ARGB to I400. 251 | LIBYUV_API 252 | int ARGBToI400(const uint8_t* src_argb, 253 | int src_stride_argb, 254 | uint8_t* dst_y, 255 | int dst_stride_y, 256 | int width, 257 | int height); 258 | 259 | // Convert ARGB to G. (Reverse of J400toARGB, which replicates G back to ARGB) 260 | LIBYUV_API 261 | int ARGBToG(const uint8_t* src_argb, 262 | int src_stride_argb, 263 | uint8_t* dst_g, 264 | int dst_stride_g, 265 | int width, 266 | int height); 267 | 268 | // Convert ARGB To NV12. 269 | LIBYUV_API 270 | int ARGBToNV12(const uint8_t* src_argb, 271 | int src_stride_argb, 272 | uint8_t* dst_y, 273 | int dst_stride_y, 274 | uint8_t* dst_uv, 275 | int dst_stride_uv, 276 | int width, 277 | int height); 278 | 279 | // Convert ARGB To NV21. 280 | LIBYUV_API 281 | int ARGBToNV21(const uint8_t* src_argb, 282 | int src_stride_argb, 283 | uint8_t* dst_y, 284 | int dst_stride_y, 285 | uint8_t* dst_vu, 286 | int dst_stride_vu, 287 | int width, 288 | int height); 289 | 290 | // Convert ABGR To NV12. 291 | LIBYUV_API 292 | int ABGRToNV12(const uint8_t* src_abgr, 293 | int src_stride_abgr, 294 | uint8_t* dst_y, 295 | int dst_stride_y, 296 | uint8_t* dst_uv, 297 | int dst_stride_uv, 298 | int width, 299 | int height); 300 | 301 | // Convert ABGR To NV21. 302 | LIBYUV_API 303 | int ABGRToNV21(const uint8_t* src_abgr, 304 | int src_stride_abgr, 305 | uint8_t* dst_y, 306 | int dst_stride_y, 307 | uint8_t* dst_vu, 308 | int dst_stride_vu, 309 | int width, 310 | int height); 311 | 312 | // Convert ARGB To YUY2. 313 | LIBYUV_API 314 | int ARGBToYUY2(const uint8_t* src_argb, 315 | int src_stride_argb, 316 | uint8_t* dst_yuy2, 317 | int dst_stride_yuy2, 318 | int width, 319 | int height); 320 | 321 | // Convert ARGB To UYVY. 322 | LIBYUV_API 323 | int ARGBToUYVY(const uint8_t* src_argb, 324 | int src_stride_argb, 325 | uint8_t* dst_uyvy, 326 | int dst_stride_uyvy, 327 | int width, 328 | int height); 329 | 330 | // RAW to JNV21 full range NV21 331 | LIBYUV_API 332 | int RAWToJNV21(const uint8_t* src_raw, 333 | int src_stride_raw, 334 | uint8_t* dst_y, 335 | int dst_stride_y, 336 | uint8_t* dst_vu, 337 | int dst_stride_vu, 338 | int width, 339 | int height); 340 | 341 | #ifdef __cplusplus 342 | } // extern "C" 343 | } // namespace libyuv 344 | #endif 345 | 346 | #endif // INCLUDE_LIBYUV_CONVERT_FROM_ARGB_H_ 347 | -------------------------------------------------------------------------------- /bitmapscaler/src/main/cpp/libyuv/libyuv/scale.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2011 The LibYuv Project Authors. All rights reserved. 3 | * 4 | * Use of this source code is governed by a BSD-style license 5 | * that can be found in the LICENSE file in the root of the source 6 | * tree. An additional intellectual property rights grant can be found 7 | * in the file PATENTS. All contributing project authors may 8 | * be found in the AUTHORS file in the root of the source tree. 9 | */ 10 | 11 | #ifndef INCLUDE_LIBYUV_SCALE_H_ 12 | #define INCLUDE_LIBYUV_SCALE_H_ 13 | 14 | #include "libyuv/basic_types.h" 15 | 16 | #ifdef __cplusplus 17 | namespace libyuv { 18 | extern "C" { 19 | #endif 20 | 21 | // Supported filtering. 22 | typedef enum FilterMode { 23 | kFilterNone = 0, // Point sample; Fastest. 24 | kFilterLinear = 1, // Filter horizontally only. 25 | kFilterBilinear = 2, // Faster than box, but lower quality scaling down. 26 | kFilterBox = 3 // Highest quality. 27 | } FilterModeEnum; 28 | 29 | // Scale a YUV plane. 30 | LIBYUV_API 31 | void ScalePlane(const uint8_t* src, 32 | int src_stride, 33 | int src_width, 34 | int src_height, 35 | uint8_t* dst, 36 | int dst_stride, 37 | int dst_width, 38 | int dst_height, 39 | enum FilterMode filtering); 40 | 41 | LIBYUV_API 42 | void ScalePlane_16(const uint16_t* src, 43 | int src_stride, 44 | int src_width, 45 | int src_height, 46 | uint16_t* dst, 47 | int dst_stride, 48 | int dst_width, 49 | int dst_height, 50 | enum FilterMode filtering); 51 | 52 | // Sample is expected to be in the low 12 bits. 53 | LIBYUV_API 54 | void ScalePlane_12(const uint16_t* src, 55 | int src_stride, 56 | int src_width, 57 | int src_height, 58 | uint16_t* dst, 59 | int dst_stride, 60 | int dst_width, 61 | int dst_height, 62 | enum FilterMode filtering); 63 | 64 | // Scales a YUV 4:2:0 image from the src width and height to the 65 | // dst width and height. 66 | // If filtering is kFilterNone, a simple nearest-neighbor algorithm is 67 | // used. This produces basic (blocky) quality at the fastest speed. 68 | // If filtering is kFilterBilinear, interpolation is used to produce a better 69 | // quality image, at the expense of speed. 70 | // If filtering is kFilterBox, averaging is used to produce ever better 71 | // quality image, at further expense of speed. 72 | // Returns 0 if successful. 73 | 74 | LIBYUV_API 75 | int I420Scale(const uint8_t* src_y, 76 | int src_stride_y, 77 | const uint8_t* src_u, 78 | int src_stride_u, 79 | const uint8_t* src_v, 80 | int src_stride_v, 81 | int src_width, 82 | int src_height, 83 | uint8_t* dst_y, 84 | int dst_stride_y, 85 | uint8_t* dst_u, 86 | int dst_stride_u, 87 | uint8_t* dst_v, 88 | int dst_stride_v, 89 | int dst_width, 90 | int dst_height, 91 | enum FilterMode filtering); 92 | 93 | LIBYUV_API 94 | int I420Scale_16(const uint16_t* src_y, 95 | int src_stride_y, 96 | const uint16_t* src_u, 97 | int src_stride_u, 98 | const uint16_t* src_v, 99 | int src_stride_v, 100 | int src_width, 101 | int src_height, 102 | uint16_t* dst_y, 103 | int dst_stride_y, 104 | uint16_t* dst_u, 105 | int dst_stride_u, 106 | uint16_t* dst_v, 107 | int dst_stride_v, 108 | int dst_width, 109 | int dst_height, 110 | enum FilterMode filtering); 111 | 112 | LIBYUV_API 113 | int I420Scale_12(const uint16_t* src_y, 114 | int src_stride_y, 115 | const uint16_t* src_u, 116 | int src_stride_u, 117 | const uint16_t* src_v, 118 | int src_stride_v, 119 | int src_width, 120 | int src_height, 121 | uint16_t* dst_y, 122 | int dst_stride_y, 123 | uint16_t* dst_u, 124 | int dst_stride_u, 125 | uint16_t* dst_v, 126 | int dst_stride_v, 127 | int dst_width, 128 | int dst_height, 129 | enum FilterMode filtering); 130 | 131 | // Scales a YUV 4:4:4 image from the src width and height to the 132 | // dst width and height. 133 | // If filtering is kFilterNone, a simple nearest-neighbor algorithm is 134 | // used. This produces basic (blocky) quality at the fastest speed. 135 | // If filtering is kFilterBilinear, interpolation is used to produce a better 136 | // quality image, at the expense of speed. 137 | // If filtering is kFilterBox, averaging is used to produce ever better 138 | // quality image, at further expense of speed. 139 | // Returns 0 if successful. 140 | 141 | LIBYUV_API 142 | int I444Scale(const uint8_t* src_y, 143 | int src_stride_y, 144 | const uint8_t* src_u, 145 | int src_stride_u, 146 | const uint8_t* src_v, 147 | int src_stride_v, 148 | int src_width, 149 | int src_height, 150 | uint8_t* dst_y, 151 | int dst_stride_y, 152 | uint8_t* dst_u, 153 | int dst_stride_u, 154 | uint8_t* dst_v, 155 | int dst_stride_v, 156 | int dst_width, 157 | int dst_height, 158 | enum FilterMode filtering); 159 | 160 | LIBYUV_API 161 | int I444Scale_16(const uint16_t* src_y, 162 | int src_stride_y, 163 | const uint16_t* src_u, 164 | int src_stride_u, 165 | const uint16_t* src_v, 166 | int src_stride_v, 167 | int src_width, 168 | int src_height, 169 | uint16_t* dst_y, 170 | int dst_stride_y, 171 | uint16_t* dst_u, 172 | int dst_stride_u, 173 | uint16_t* dst_v, 174 | int dst_stride_v, 175 | int dst_width, 176 | int dst_height, 177 | enum FilterMode filtering); 178 | 179 | LIBYUV_API 180 | int I444Scale_12(const uint16_t* src_y, 181 | int src_stride_y, 182 | const uint16_t* src_u, 183 | int src_stride_u, 184 | const uint16_t* src_v, 185 | int src_stride_v, 186 | int src_width, 187 | int src_height, 188 | uint16_t* dst_y, 189 | int dst_stride_y, 190 | uint16_t* dst_u, 191 | int dst_stride_u, 192 | uint16_t* dst_v, 193 | int dst_stride_v, 194 | int dst_width, 195 | int dst_height, 196 | enum FilterMode filtering); 197 | 198 | // Scales a YUV 4:2:2 image from the src width and height to the 199 | // dst width and height. 200 | // If filtering is kFilterNone, a simple nearest-neighbor algorithm is 201 | // used. This produces basic (blocky) quality at the fastest speed. 202 | // If filtering is kFilterBilinear, interpolation is used to produce a better 203 | // quality image, at the expense of speed. 204 | // If filtering is kFilterBox, averaging is used to produce ever better 205 | // quality image, at further expense of speed. 206 | // Returns 0 if successful. 207 | LIBYUV_API 208 | int I422Scale(const uint8_t* src_y, 209 | int src_stride_y, 210 | const uint8_t* src_u, 211 | int src_stride_u, 212 | const uint8_t* src_v, 213 | int src_stride_v, 214 | int src_width, 215 | int src_height, 216 | uint8_t* dst_y, 217 | int dst_stride_y, 218 | uint8_t* dst_u, 219 | int dst_stride_u, 220 | uint8_t* dst_v, 221 | int dst_stride_v, 222 | int dst_width, 223 | int dst_height, 224 | enum FilterMode filtering); 225 | 226 | LIBYUV_API 227 | int I422Scale_16(const uint16_t* src_y, 228 | int src_stride_y, 229 | const uint16_t* src_u, 230 | int src_stride_u, 231 | const uint16_t* src_v, 232 | int src_stride_v, 233 | int src_width, 234 | int src_height, 235 | uint16_t* dst_y, 236 | int dst_stride_y, 237 | uint16_t* dst_u, 238 | int dst_stride_u, 239 | uint16_t* dst_v, 240 | int dst_stride_v, 241 | int dst_width, 242 | int dst_height, 243 | enum FilterMode filtering); 244 | 245 | LIBYUV_API 246 | int I422Scale_12(const uint16_t* src_y, 247 | int src_stride_y, 248 | const uint16_t* src_u, 249 | int src_stride_u, 250 | const uint16_t* src_v, 251 | int src_stride_v, 252 | int src_width, 253 | int src_height, 254 | uint16_t* dst_y, 255 | int dst_stride_y, 256 | uint16_t* dst_u, 257 | int dst_stride_u, 258 | uint16_t* dst_v, 259 | int dst_stride_v, 260 | int dst_width, 261 | int dst_height, 262 | enum FilterMode filtering); 263 | 264 | // Scales an NV12 image from the src width and height to the 265 | // dst width and height. 266 | // If filtering is kFilterNone, a simple nearest-neighbor algorithm is 267 | // used. This produces basic (blocky) quality at the fastest speed. 268 | // If filtering is kFilterBilinear, interpolation is used to produce a better 269 | // quality image, at the expense of speed. 270 | // kFilterBox is not supported for the UV channel and will be treated as 271 | // bilinear. 272 | // Returns 0 if successful. 273 | 274 | LIBYUV_API 275 | int NV12Scale(const uint8_t* src_y, 276 | int src_stride_y, 277 | const uint8_t* src_uv, 278 | int src_stride_uv, 279 | int src_width, 280 | int src_height, 281 | uint8_t* dst_y, 282 | int dst_stride_y, 283 | uint8_t* dst_uv, 284 | int dst_stride_uv, 285 | int dst_width, 286 | int dst_height, 287 | enum FilterMode filtering); 288 | 289 | #ifdef __cplusplus 290 | // Legacy API. Deprecated. 291 | LIBYUV_API 292 | int Scale(const uint8_t* src_y, 293 | const uint8_t* src_u, 294 | const uint8_t* src_v, 295 | int src_stride_y, 296 | int src_stride_u, 297 | int src_stride_v, 298 | int src_width, 299 | int src_height, 300 | uint8_t* dst_y, 301 | uint8_t* dst_u, 302 | uint8_t* dst_v, 303 | int dst_stride_y, 304 | int dst_stride_u, 305 | int dst_stride_v, 306 | int dst_width, 307 | int dst_height, 308 | LIBYUV_BOOL interpolate); 309 | 310 | // For testing, allow disabling of specialized scalers. 311 | LIBYUV_API 312 | void SetUseReferenceImpl(LIBYUV_BOOL use); 313 | #endif // __cplusplus 314 | 315 | #ifdef __cplusplus 316 | } // extern "C" 317 | } // namespace libyuv 318 | #endif 319 | 320 | #endif // INCLUDE_LIBYUV_SCALE_H_ 321 | --------------------------------------------------------------------------------