Skip to content

License Guide

Version: 1.0.3
Platform: Android arm64-v8a · Linux aarch64


Overview

ACL Pack uses a file-based license system with cryptographic signature verification. Each license is bound to:

  • licenseId — unique identifier traceable in our delivery ledger
  • Tier — must match the compiled library tier (Trial / Starter / Pro / Business)
  • Issue date — the date the license was signed
  • Recorded expiration — subscription service window; tracks how long you remain eligible for updates and support. The library you received continues to work within the scope of your purchase agreement after the window ends; renewal keeps you eligible for newer versions.

Subscription services during the validity window

The recorded validity is 1 year (extendable via renewal). During this window we proactively push to your licenseId:

  • New operators — freshly released NEON / CPP implementations
  • Performance optimizations — faster versions of existing operators
  • Bug fixes — compatibility, edge cases, stability improvements
  • Platform expansion — e.g., additional Android ABIs (armeabi-v7a / x86_64), additional Linux distributions, iOS port (subject to your tier; Linux aarch64 already ships in v1.0.3)
  • Technical support — Pro / Business / Enterprise get priority email or dedicated engineer response

After the window ends, the version you already received continues to work within the scope of your purchase agreement; to receive newer versions or performance improvements, renew the subscription. See Pricing for details.

The license is not bound to an Android package name or APK signing certificate. You may deploy the licensed library in any app you own under the terms of your purchase, without re-requesting a license when your signing key changes or during debug / release builds.

Redistribution, OEM-style resale, or sharing the library with another company is not covered by your purchase. Any such act will be pursued through legal channels — full terms in README.md / README_CN.md shipped with every SDK.

How You Receive a License

Taobao purchase (standard tiers)

After checkout on our Taobao store, the order is fulfilled automatically:

  1. A license.dat is allocated to your order
  2. You receive the SDK zip + license.dat via Taobao message
  3. Your order is bound to the license for after-sales support (renewal, reissue)

No sign-up, email exchange, or technical details required. Open the zip, drop the .a and headers into your project, place license.dat next to them, and build.

Enterprise OEM / Source

For per-OEM builds (see pricing page), reach out to zangotech@163.com — we will provide the OEM contract template and commercial onboarding.

About the License File

license.dat is a signed text file. Do not modify it — any edit invalidates the signature, and acl::init() will return -1001. Use the file exactly as delivered.

Ownership terms

Within the scope of your purchase agreement, you may continue using the version you received. Renewing your subscription keeps you eligible for future updates (new operators, performance improvements). Usage outside the purchased scope is covered by the redistribution clause above.

Setup Steps

1. Place the License File

Copy license.dat into your app's assets directory:

app/src/main/assets/license.dat

Or any path accessible at runtime (e.g., internal storage after first-launch copy).

2. Initialize at App Startup

Call acl::init() once before using any ACL Pack operator.

Native C++ (recommended):

cpp
#include <acl/acl.h>

// Path to license.dat on device — resolve from your app's writable storage,
// e.g. Android: Context.getFilesDir() + "/license.dat" passed through JNI;
// Linux: any path your process can read.
const char* licensePath = /* absolute path, see §3 for the Android pattern */;

int ret = acl::init(licensePath);
if (ret != 0) {
    // Handle license error — see Error Codes below
}

Parameters:

ParameterTypeDescription
licensePathconst char*Absolute path to license.dat your process can read
env (reserved)JNIEnv*Reserved in the ABI; the current implementation does not read it. Pass nullptr.
context (reserved)jobjectReserved in the ABI; the current implementation does not read it. Pass nullptr.

Full signature: int acl::init(const char* licensePath, JNIEnv* env = nullptr, jobject context = nullptr);. Just pass licensePath — the two trailing parameters are kept for ABI stability and are ignored by v1.0.3.

acl::init() runs once per process. After the first call, subsequent calls return the same status without re-reading the file. It must return 0 before you invoke any operator, otherwise operator calls return -1001 (ACL_ERR_LICENSE_INVALID). acl::init and acl::version are safe to call first.

3. JNI Integration (Android)

Typical pattern: copy license.dat from APK assets to internal storage on first launch, then pass the absolute path to native code.

java
// In your Activity/Application — once at startup
File licenseFile = new File(context.getFilesDir(), "license.dat");
if (!licenseFile.exists()) {
    try (InputStream is = context.getAssets().open("license.dat");
         OutputStream os = new FileOutputStream(licenseFile)) {
        byte[] buf = new byte[4096];
        int n;
        while ((n = is.read(buf)) > 0) os.write(buf, 0, n);
    }
}
int rc = nativeInitAcl(licenseFile.getAbsolutePath());  // calls acl::init via JNI

On the native side, forward the jstring to acl::init as a UTF-8 C-string. A complete JNI wrapper example (Java class + JNI extern "C" function) is in the Integration Guide.

4. Linux aarch64 Integration

On Linux aarch64, place license.dat next to your binary or anywhere your process can read, then pass the absolute path directly:

cpp
#include <acl/acl.h>
#include <cstdio>

int main() {
    int ret = acl::init("/opt/myapp/license.dat");
    if (ret != 0) {
        fprintf(stderr, "acl::init failed: %d\n", ret);
        return 1;
    }
    // proceed to call ACL Pack operators...
    return 0;
}

Link line example:

g++ -std=c++17 main.cpp \
    -I/path/to/sdk/include \
    /path/to/sdk/lib/linux-aarch64/libacl.a \
    -lpthread -o myapp

The Linux aarch64 delivery zip lays out files as lib/linux-aarch64/libacl.a + include/acl/*.h + license.dat — drop them into your project and link.

Error Codes

CodeMacroMeaningAction
0ACL_OKLicense validProceed normally
-1001ACL_ERR_LICENSE_INVALIDLicense file missing, corrupt, tampered, or acl::init() has not succeeded yetCheck file path and integrity; confirm init() was called before any operator and returned 0
-1005ACL_ERR_NOT_LICENSEDTier mismatch: either acl::init detected license.tier does not match the compiled library tier, or the operator invoked at runtime is not available in the current tierPair the license with the library of the same tier; or upgrade tier; or pick an operator available in your tier
-1006ACL_ERR_RESOLUTION_LIMITResolution does not match the Trial fixed size (1920×1280)Upgrade from Trial (no resolution limit)

Tier System

ACL Pack is distributed in 4 standard tiers. Your license must match the .a library tier exactly. The library file is always named libacl.a — the tier identity lives inside the binary and inside license.dat, not in the filename.

TierOperator familiesPixel TypesNotes
Trial1 op / 2 fixed entry pointsuint8_tWatermark + strict 1920×1280 fixed size
Starter57uint8_tEssential operators
Pro100uint8_t, uint16_t+ bilateral, CLAHE, matchTemplate, etc.
Business113uint8_t, uint16_t, floatAll standard operators; standard pixel types where supported per operator

Operator counts in this table are documented operator families (CPP and NEON variants of the same operator share one row). Enterprise-custom fused pipelines are outside the standard tier count. Counted as customer-facing callable entries (including N-image variants, kernel-size dispatchers, and CPP/NEON pairs that ship as separate functions), the Business tier exposes 163 entries.

See Operator Tiers for the complete operator list per tier.

Tier mismatch example: If you have a Starter license but link against the Business-tier libacl.a, acl::init() returns -1005 (ACL_ERR_NOT_LICENSED, tier mismatch). Always pair the license.dat from your delivery zip with the libacl.a from the same zip.

License Renewal & Reissue

"Renewal" and "reissue" are two different actions. Send the same three items either way; the difference is what we do on our side.

For both, send to zangotech@163.com or via Taobao after-sales:

  1. Your Taobao buyer ID
  2. The original Taobao order number
  3. Your existing license.datattach the file (preferred; pasting the text risks truncating the signature block)

Renewal (extend the subscription window)

When your 1-year subscription window is approaching its end and you want to keep receiving new operators / performance updates / bug fixes, request a renewal. Pricing is on the Pricing page.

  • Your licenseId stays the same
  • We extend the expireDate in the ledger and re-sign a fresh license.dat
  • Your existing libacl.a keeps working — only license.dat is replaced
  • Within one business day

Reissue (replace a lost or damaged license file)

When the license.dat was lost, accidentally edited, or you need a fresh copy for any reason — and you are still within the same purchase scope (same tier, same slot).

  • A new licenseId is assigned and appended to the ledger; the previous licenseId is marked superseded
  • libacl.a does not change — same slot, same library, only license.dat is replaced
  • No re-issue limit, but each reissue is logged for traceability
  • Within one business day

Changing devices, app, or signing certificate

Within the scope of your purchase agreement, the license is not bound to package name, signing certificate, or device serial. Switching debug/release builds, repackaging, deploying to a new device under the same app — none of these require a new license.

If you need a different tier, a different platform (Android ↔ Linux), or you want a separate slot for a separate product line, that's a new order, not a reissue. Contact us first if you're unsure which path applies.

After renewal or reissue, drop the new license.dat in place of the old one — no code changes needed.

Security Notes

  • The license file is read-only — ACL Pack never writes to disk
  • Cryptographic signing prevents tampering — any edit to license.dat invalidates it
  • Operator calls require a valid initialized license; otherwise they return -1001
  • String encryption and symbol obfuscation harden the library against reverse engineering
  • Traceability: every issued licenseId is recorded against the Taobao order. Leaked or redistributed licenses can be traced back to the source of the leak.

Troubleshooting

SymptomLikely CauseSolution
Returns -1001 on every launchWrong file path, or init() not calledLog licensePath, verify file exists, confirm acl::init() is invoked before any operator
Returns -1001 after editing the fileAny modification breaks the signatureUse the original license.dat as delivered
Every operator returns -1001init() has not succeededCheck init() return value — it must be 0
Returns -1005Tier mismatch (at init) or operator not in current tier (at call site)Check libacl_{tier}.a matches license tier; or upgrade tier
Returns -1006Resolution is not 1920×1280Trial requires exactly 1920×1280; non-Trial tiers have no such limit