Skip to content

ENG-58732 NFC - ship the JPEG 2000 decoder under a prefixed native library name [M] - #1

Open
UkiUros wants to merge 4 commits into
masterfrom
ENG-58732-incode-jp2
Open

UkiUros wants to merge 4 commits into
masterfrom
ENG-58732-incode-jp2

Conversation

@UkiUros

@UkiUros UkiUros commented Oct 26, 2026 •

Copy link
Copy Markdown

The decoder uses libopenjpeg.so and com.gemalto.jp2, which can conflict with another JPEG 2000 dependency in the same app.

This fork of Thales JP2ForAndroid 1.1.0 retains OpenJPEG 2.5.4 and publishes com.incode.sdk:jp2-android:1.1.0-incode.1.
It renames the Java package to com.incode.jp2 and the native library to libincode-openjpeg.so.
The native export map exposes only JNI entry points.
The build retains all four ABIs and 16 KB alignment.

GitHub Actions builds, lints, and uploads the AAR and staged Maven files as workflow artifacts.
Maven publication remains a separate, explicit script operation.

Test: Release build and lint passed locally and in GitHub Actions.
All 26 upstream native tests passed on ARM emulators with 4 KB and 16 KB pages.
Two coexistence tests passed with the original decoder, including both load orders and the staged AAR.
ELF checks passed for all four ABIs: 16 KB LOAD alignment, renamed SONAME, and isolated exports.

Manual check: In an SDK consumer app, read a passport with a JPEG 2000 portrait in debug and protected release builds.
Repeat with another dependency that supplies libopenjpeg.so, without native-library packaging workarounds.
The portrait must display without a crash or decoding error.

Notes for review: The library requires compileSdk 36 and retains minSdk 16.
Cloud-built artifacts do not replace the version already published from the validated local build.
The uploader now preserves staging paths with spaces; a local HTTP test covers publication, metadata, retries, and conflict rejection.
The upload conflict checks are not an atomic lock.
Concurrent publication still needs server-side no-redeploy protection or a shared publisher lock; that review finding remains open.

Acceptance criteria:

  • Renamed Java package and native library; all four ABIs retain 16 KB alignment.
  • Automated native decoding and coexistence tests pass.
  • SDK consumer collision test and real passport portrait pass in debug and protected release builds.
  • SDK size measurement and named manual test-document evidence are attached to the integration review.

Review effort estimate: ~1.5-2 hrs (M). This is a heuristic estimate that includes native packaging, publication, and device checks.

Context for AI agents

The published AAR SHA-256 is c6905c951f71e173a2e501d92ef405258a00e0c42c8890b0802de4f5d38e2cae.
The source implementation commit is 1f38c8a; later commits add publication scripts and CI.
The coexistence fixture uses dev.keiji.jp2:jp2-android:1.0.5 only in the test app.
The version script hides OpenJPEG implementation symbols to avoid interposition across separately loaded libraries.
Physical passport and protected SDK runtime checks remain pending.

@UkiUros UkiUros self-assigned this Oct 26, 2026
@UkiUros UkiUros added this to the 5.56.0 milestone Oct 26, 2026
@UkiUros
UkiUros requested a balanced review from Copilot October 26, 2026 12:59

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The publication script needs reliable release immutability under concurrent uploads and correct handling of staging paths containing spaces.

2 open issues
What changed in this PR

This PR isolates the forked JPEG 2000 codec from other Android decoder dependencies by renaming its Java package and native library while retaining OpenJPEG 2.5.4.

Changes:

  • Renames the codec to com.incode.jp2 and libincode-openjpeg.so, restricts native exports, and preserves 16 KB alignment.
  • Adds coexistence tests and staged-AAR testing.
  • Adds Maven staging, explicit publication scripts, and GitHub Actions build artifacts.
File Description
testapp/​src/​main/​java/​com/​incode/​jp2/​test/​MainActivity.java Updates the package and decoder import.
testapp/​src/​androidTest/​java/​com/​incode/​jp2/​test/​TestDecoderCoexistence.java Tests decoder coexistence and truncated input.
testapp/​build.gradle Adds the second decoder and staged-artifact testing.
scripts/​uploadStagedRepo.sh Uploads staged Maven files with conflict checks and metadata merging.
scripts/​mavenRepoCredentials.sh Reads credentials and supplies curl authentication.
README.md Documents build, publication, and validation procedures.
library/​src/​main/​java/​com/​incode/​jp2/​JP2Encoder.java Renames the package and native library load.
library/​src/​main/​java/​com/​incode/​jp2/​JP2Decoder.java Renames the package and native library load.
library/​src/​main/​cpp/​openjpg.cpp Renames JNI entry points.
library/​src/​androidTest/​java/​com/​incode/​jp2/​Util.java Migrates the test utility package.
library/​src/​androidTest/​java/​com/​incode/​jp2/​TestJp2Encoder.java Migrates encoder tests to the new package.
library/​src/​androidTest/​java/​com/​incode/​jp2/​TestJp2Decoder.java Migrates decoder tests to the new package.
library/​exports.map Restricts exports to JNI entry points.
library/​consumer-rules.pro Preserves native method names during obfuscation.
library/​CMakeLists.txt Renames the native target and applies export isolation.
library/​build.gradle Configures fork coordinates, build settings, and Maven staging.
gradle/​wrapper/​gradle-wrapper.properties Selects Gradle 8.14.5.
build.gradle Selects Android Gradle Plugin 8.9.1.
.github/​workflows/​build-aar.yml Builds, lints, stages, and uploads artifacts.

Review effort: Balanced

upload() {
local file="$1"
local path="${file#"$repo_dir"/}"
if ! auth_curl --fail --silent --show-error --retry 3 --upload-file "$file" "$repo_url/$path" > /dev/null; then
Comment thread scripts/uploadStagedRepo.sh Resolved

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Concurrent publishers can silently lose Maven metadata versions because readback verification does not make updates atomic.

2 open issues
1 resolved since last review

Review effort: Balanced

Comment on lines +216 to +219
download_metadata "$artifact_path" "$remote_metadata"
missing=$(missing_versions "$remote_metadata" "${versions[@]}")
rm -f "$remote_metadata"
[ -z "$missing" ] && break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants