Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
eb41e28
Make the project buildable with modern sdk again
Lolle2000la Mar 1, 2026
f89e97d
Also make the project work with current versions of Android Studio
Lolle2000la Mar 1, 2026
dfb2eb8
Setup the build environment for the rust crate
Lolle2000la Mar 2, 2026
3fa2d8c
Add Rect and ImageInfo structs with associated methods for image proc…
Lolle2000la Mar 2, 2026
36326a6
Reimplement the border finding logic
Lolle2000la Mar 2, 2026
886393d
Implement image decoding support for multiple formats (PNG, WebP, HEI…
Lolle2000la Mar 2, 2026
e317bdf
Add ICC color transformation function for RGBA pixels
Lolle2000la Mar 2, 2026
deab1d8
Implement image type detection and format identification from file he…
Lolle2000la Mar 2, 2026
ac1f920
Implement downsample_region function for image resizing
Lolle2000la Mar 2, 2026
6ceb407
Add core modules and JNI integration for image decoding
Lolle2000la Mar 2, 2026
3c36363
Add integration tests for image decoding and format detection
Lolle2000la Mar 2, 2026
30ba292
Import correct repo for rust-plugin, use the latest version that came…
Lolle2000la Mar 2, 2026
42a56f1
Add native-libs directory to .gitignore for Rust integration
Lolle2000la Mar 2, 2026
79a3ce6
Fix wrapper `distributionUrl` still being in the old version
Lolle2000la Mar 2, 2026
205c0e6
Update jniLibs source directories and ensure cargoBuild tasks depend …
Lolle2000la Mar 2, 2026
4a41e36
Service libheifcodec.so and upgrade it to v1.21.2 while at it
Lolle2000la Mar 2, 2026
46b2f6b
Add build script for JNI integration with Android
Lolle2000la Mar 2, 2026
7b1673a
Add 16 KB page-size alignment for Android 15+ devices in CMake and Ru…
Lolle2000la Mar 2, 2026
3c26f02
Create benchmarks
Lolle2000la Mar 2, 2026
e772309
Refactor pixel transformation to optimize alpha channel handling
Lolle2000la Mar 2, 2026
9c4898f
Add release profile to cargo configuration in build.gradle
Lolle2000la Mar 2, 2026
cc769f8
Add release profile configuration to Cargo.toml
Lolle2000la Mar 2, 2026
c424c67
Refactor downsample_region to optimize cropping and memory handling
Lolle2000la Mar 2, 2026
1590400
Refactor grayscale conversion in parse_info to use iterator for impro…
Lolle2000la Mar 2, 2026
cc0fb2f
Refactor decode_rgba to use chunk iterators for improved performance …
Lolle2000la Mar 2, 2026
6903146
Refactor nativeDecode to eliminate unnecessary buffer allocation and …
Lolle2000la Mar 2, 2026
501249d
Refactor color conversion to use rgb_to_luma function for improved re…
Lolle2000la Mar 2, 2026
f655e19
Refactor color conversion to use rgb_to_luma function for improved re…
Lolle2000la Mar 2, 2026
bb634af
Move more conditions out of the loops and use iterators for more opti…
Lolle2000la Mar 2, 2026
2f4b10d
Refactor decode_rgba to use a helper function for color conversion, i…
Lolle2000la Mar 2, 2026
ec8aa25
Refactor decode_rgba to use stream for direct buffer writing, improvi…
Lolle2000la Mar 2, 2026
35f23c4
Replace jxl-oxide with vendored jpegxl-rs
Lolle2000la Mar 3, 2026
271afd6
Simplify resize logic, evade more copies and use bicubic filtering in…
Lolle2000la Mar 3, 2026
5075f2c
Update fast_image_resize dependency to enable rayon feature for impro…
Lolle2000la Mar 3, 2026
8a516e3
Refactor transform_pixels to save alpha values before in-place transf…
Lolle2000la Mar 3, 2026
e2ea7d3
Optimize grayscale conversion by modifying RGBA data in-place, reduci…
Lolle2000la Mar 3, 2026
42a8dc9
Refactor JxlDecoder to read basic info directly from the header and o…
Lolle2000la Mar 3, 2026
df5860b
Refactor PNG decoding to stream rows directly into the RGBA buffer, e…
Lolle2000la Mar 3, 2026
07c1765
Refactor WebP decoding to retrieve image dimensions from the bitstrea…
Lolle2000la Mar 3, 2026
4aaca1b
Update dependencies in Cargo.toml and Cargo.lock to include jpegxl-sy…
Lolle2000la Mar 3, 2026
dab4c69
Update test images (including generation) to create a 6400×3600 gradi…
Lolle2000la Mar 3, 2026
e447546
Utilize cropping in `fast_image_resize` crate instead of doing it our…
Lolle2000la Mar 3, 2026
aeceddb
Refactor JPEG decoding to use RGB instead of RGBA for faster processi…
Lolle2000la Mar 3, 2026
849de19
Refactor WebP decoding to optimize grayscale conversion and expand RG…
Lolle2000la Mar 3, 2026
1a6531d
Replace zune-jpeg with turbojpeg (libjpeg-turbo bindings)
Lolle2000la Mar 3, 2026
6d460e6
Use scaling factors to scale down much more efficiently on regions
Lolle2000la Mar 3, 2026
37dc982
Hook Cargo build tasks into the Android build process to ensure prope…
Lolle2000la Mar 3, 2026
4a5676e
Add rustflags for aarch64-linux-android target to enable NEON support
Lolle2000la Mar 3, 2026
e45bb5a
Add VSCode settings for Rust Analyzer project linking
Lolle2000la Mar 3, 2026
ac8f7e3
Optimize grayscale decoding by using Vec::with_capacity and avoiding …
Lolle2000la Mar 3, 2026
482a558
Make use of a stride optimization if possible to increase heif decode…
Lolle2000la Mar 3, 2026
590f5ff
Use the webp-lib more directly through `libwebp_sys` crate
Lolle2000la Mar 3, 2026
4076b67
Enhance WebpDecoder's decode method with overflow checks and buffer s…
Lolle2000la Mar 3, 2026
8c0f999
Prevent accidental overflow panics in unsafe code
Lolle2000la Mar 3, 2026
1704ba6
Use the `libjpeg-turbo` library directly to work around the wrapper …
Lolle2000la Mar 3, 2026
f614f27
Allow switching between the old backend and the new backend
Lolle2000la Mar 4, 2026
3c7e8f3
chore: rustfmt
Lolle2000la Mar 4, 2026
2638db1
Refactor HeifDecoder's decode method to use and iterator instead of p…
Lolle2000la Mar 4, 2026
229850c
Refactor PNG decoding to eliminate unsafe code and improve memory han…
Lolle2000la Mar 4, 2026
5b9b879
Refactor WebP decoding to eliminate unsafe buffer handling and improv…
Lolle2000la Mar 4, 2026
d547b37
Prevent naming collision between the benchmark C++ lib and the old-ba…
Lolle2000la Mar 4, 2026
1e23248
Set ImageDecoder backend to Rust in DecodeBenchmark setup
Lolle2000la Mar 4, 2026
83c37f4
Fix gradle and kotlin warnings
Lolle2000la Mar 4, 2026
7e188aa
Return an error instead of panicking
Lolle2000la Mar 4, 2026
0b78b0a
Add dimension check helper to prevent oversized image decoding
Lolle2000la Mar 4, 2026
3f9899c
Enhance WebpDecoder to include ICC profile handling and implement ani…
Lolle2000la Mar 4, 2026
8652c57
Implement ICC profile extraction for JPEG, WebP, and PNG formats
Lolle2000la Mar 4, 2026
9fc502c
Add ICC profile extraction and color transformation support in JxlDec…
Lolle2000la Mar 4, 2026
2704381
Add ICC profile extraction and color transformation support in JpegDe…
Lolle2000la Mar 4, 2026
a5f66eb
Add ICC profile extraction and color transformation support in HeifDe…
Lolle2000la Mar 4, 2026
94a7378
Add ICC profile extraction and color transformation support in PngDec…
Lolle2000la Mar 4, 2026
3a32cd7
Add WebP animation detection and ICC profile extraction tests
Lolle2000la Mar 4, 2026
781152a
Massively improve the regional decode scenario for jpeg decoder using…
Lolle2000la Mar 6, 2026
eefb8ab
Make use of more efficient memcpy even in the iterator based impl of …
Lolle2000la Mar 6, 2026
bfb20ca
Improve JXL border cropping by directly decoding to 1 channel
Lolle2000la Mar 6, 2026
1b43769
Make use of more efficient memcpy even in the iterator based impl of …
Lolle2000la Mar 6, 2026
2563940
Optimize HEIF decoding by correctly allowing more through the happy d…
Lolle2000la Mar 6, 2026
5e1ac9f
Optimize HEIF decoding by conditionally handling alpha channels to re…
Lolle2000la Mar 6, 2026
0faadc4
Fix clippy warnings
Lolle2000la Mar 6, 2026
44e7bf2
Refactor PNG and HEIF decoding to avoid zero-filling buffers in a sou…
Lolle2000la Mar 6, 2026
63afd6b
Fix happy path condition causing AVIF to no longer load
Lolle2000la Mar 6, 2026
8ee7f48
Refactor downsample_region to use thread-local resizer to reduce cons…
Lolle2000la Mar 8, 2026
9ff72d7
Remove unused lcms_in_type method from Decoder implementations
Lolle2000la Mar 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,11 @@
.externalNativeBuild
.cxx
local.properties

# Rust
**/target/
**/*.rs.bk
library/src/main/rust/native-libs/**

# Benchmarking
**/benchmark/build/
7 changes: 7 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"rust-analyzer.linkedProjects": [
"library/src/main/rust/core/Cargo.toml",
"library/src/main/rust/jni/Cargo.toml",
"library/src/main/rust/Cargo.toml"
]
}
78 changes: 78 additions & 0 deletions benchmark/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
plugins {
id 'com.android.library'
id 'kotlin-android'
}

android {
namespace 'tachiyomi.decoder.benchmark'
compileSdk 34
ndkVersion "26.2.11394342"

defaultConfig {
minSdk 21
targetSdk 34

testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner"

// Pass the benchmark output directory to the runner.
testInstrumentationRunnerArguments["additionalTestOutputDir"] =
"/sdcard/Download/benchmark_results"

// Allow running on emulators (results will be noisier than on real hardware).
testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "EMULATOR"

externalNativeBuild {
cmake {
abiFilters "arm64-v8a", "armeabi-v7a", "x86", "x86_64"
}
}
}

buildTypes {
release {
minifyEnabled false
}
}

compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}

// Build the C++ benchmark decoder (libimagedecoder_cpp.so).
externalNativeBuild {
cmake {
path "../library/src/main/cpp/benchmark/CMakeLists.txt"
}
}

// Note: libheifcodec.so and libimagedecoder.so are provided by the
// :library dependency (its AAR includes both native libraries).
// Do NOT add jniLibs.srcDirs here to avoid APK merge conflicts.

// Suppress the benchmark "not a release build" warning — we need
// debuggable=false in the androidTest manifest, which is already set.
testBuildType = "release"
}

dependencies {
implementation project(':library')

androidTestImplementation 'androidx.benchmark:benchmark-junit4:1.3.3'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'androidx.test:core:1.6.1'
androidTestImplementation 'androidx.test.ext:junit:1.2.1'
androidTestImplementation 'junit:junit:4.13.2'
}

afterEvaluate {
// The benchmark CMake links against libheifcodec.so at build time.
// Ensure the library module's CMake (which produces libheifcodec.so)
// runs first.
tasks.matching { it.name.startsWith("buildCMake") && it.project == project }.configureEach { benchCmakeTask ->
benchCmakeTask.dependsOn project(':library').tasks.matching { it.name.startsWith("buildCMake") }
}
}
33 changes: 33 additions & 0 deletions benchmark/src/androidTest/assets/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Benchmark Test Images

Place sample images here for benchmarking. JPEG, PNG, and WebP test images
are generated automatically (512×512 gradient) when not present, but you can
provide your own for more realistic benchmarks.

## Required filenames

| File | Format | Notes |
|-------------------|----------|--------------------------------------------|
| `test_image.jpg` | JPEG | Auto-generated if missing |
| `test_image.png` | PNG | Auto-generated if missing |
| `test_image.webp` | WebP | Auto-generated if missing |
| `test_image.heif` | HEIF | Must be provided (skipped if missing) |
| `test_image.avif` | AVIF | Must be provided (skipped if missing) |
| `test_image.jxl` | JPEG XL | Must be provided (skipped if missing) |

## Recommended test images

For best benchmark results, use images that are:

- **512×512** or **1024×1024** pixels (large enough to be meaningful)
- **Realistic** (photos or manga pages rather than solid colours)
- **Representative** of the actual workload (manga/comic pages)

You can convert between formats using ImageMagick:

```bash
# Convert a JPEG to HEIF / AVIF / JXL
convert input.jpg test_image.heif
convert input.jpg test_image.avif
cjxl input.jpg test_image.jxl
```
Binary file added benchmark/src/androidTest/assets/test_image.avif
Binary file not shown.
Binary file added benchmark/src/androidTest/assets/test_image.heif
Binary file not shown.
Binary file added benchmark/src/androidTest/assets/test_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added benchmark/src/androidTest/assets/test_image.jxl
Binary file not shown.
Binary file added benchmark/src/androidTest/assets/test_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added benchmark/src/androidTest/assets/test_image.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading