Integration Guide
Version: 1.0.3
Platforms: Android arm64-v8a / Linux aarch64
Delivery: libacl.a + include/acl/ + license.dat
This page keeps only the integration path customers need: copy the SDK files, link the static library, initialize the license, and call the first operator.
1. Prepare Files
Copy the files from the SDK zip into your project. You can adjust the paths, but this layout is recommended.
Android arm64-v8a:
your_project/
include/acl/
acl.h
api.h
err.h
typeDef.h
lib/arm64-v8a/
libacl.a
license.datLinux aarch64:
your_project/
include/acl/
acl.h
api.h
err.h
typeDef.h
lib/linux-aarch64/
libacl.a
license.datTrial packages also include include/acl/trial/api.hpp and include/acl/trial/watermark.h. Customer code usually only needs #include <acl/api.h>; include <acl/trial/api.hpp> only when you want the explicit Trial declarations.
2. Configure Build
Android CMake
cmake_minimum_required(VERSION 3.10)
project(your_app)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(acl STATIC IMPORTED)
set_target_properties(acl PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/${ANDROID_ABI}/libacl.a
)
add_library(your_app SHARED your_app.cpp)
target_include_directories(your_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(your_app acl m log atomic z)Android packages support arm64-v8a only. If you use Android.mk, the core setup is:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := acl
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libacl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := your_app
LOCAL_SRC_FILES := your_app.cpp
LOCAL_STATIC_LIBRARIES := acl
LOCAL_LDLIBS := -lm -llog -latomic -lz
include $(BUILD_SHARED_LIBRARY)Linux aarch64 CMake
Create toolchains/linux-aarch64.cmake:
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc)
set(CMAKE_CXX_COMPILER aarch64-linux-gnu-g++)
set(CMAKE_AR aarch64-linux-gnu-ar)
set(CMAKE_RANLIB aarch64-linux-gnu-ranlib)
add_compile_options(-march=armv8-a)CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)
project(your_app)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_library(acl STATIC IMPORTED)
set_target_properties(acl PROPERTIES
IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/linux-aarch64/libacl.a
)
add_executable(your_app your_app.cpp)
target_include_directories(your_app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(your_app acl m pthread)Build:
cmake -DCMAKE_TOOLCHAIN_FILE=toolchains/linux-aarch64.cmake -DCMAKE_BUILD_TYPE=Release -S . -B build
cmake --build build -jWithout CMake, a direct cross-compile command also works:
aarch64-linux-gnu-g++ -O2 -std=c++17 -Iinclude \
-o your_app your_app.cpp lib/linux-aarch64/libacl.a \
-lm -lpthread3. Initialize License
Call acl::init() once before any operator call. Pass the real path to license.dat on the device.
#include <acl/acl.h>
int ret = acl::init("/path/to/license.dat");
if (ret != 0) {
// Handle the error code. See the table below.
}On Android, do not hardcode /data/data/.... A common pattern is to copy license.dat from APK assets into Context.getFilesDir() on first launch, then pass the absolute path to native code:
File licenseFile = new File(context.getFilesDir(), "license.dat");
int ret = nativeInitAcl(licenseFile.getAbsolutePath());JNI side:
#include <jni.h>
#include <acl/acl.h>
extern "C" JNIEXPORT jint JNICALL
Java_com_yourapp_AclLicense_nativeInitAcl(JNIEnv* env, jclass,
jstring licensePath) {
const char* path = env->GetStringUTFChars(licensePath, nullptr);
int ret = acl::init(path);
env->ReleaseStringUTFChars(licensePath, path);
return ret;
}For delivery, renewal, and tier-matching rules, see the License Guide.
4. First Operator Call
Starter / Pro / Business use the general API. All public operator declarations are in <acl/api.h>:
#include <acl/acl.h>
#include <acl/api.h>
#include <cstdint>
int main() {
int ret = acl::init("license.dat");
if (ret != 0) return ret;
const int width = 1920;
const int height = 1280;
uint8_t* src = new uint8_t[width * height];
uint8_t* dst = new uint8_t[width * height];
// stride = 0 means contiguous memory. ACL computes width * channels * sizeof(T).
ret = acl::neon::filter::gaussianBlur(
src, dst,
width, height,
/*srcStride=*/0, /*dstStride=*/0,
/*kRadiusX=*/2, /*kRadiusY=*/2,
/*sigmaX=*/1.0, /*sigmaY=*/1.0);
delete[] src;
delete[] dst;
return ret;
}Common namespaces:
acl::neon::{module}::op(...): ARM NEON accelerated path, recommended on ARM64acl::{module}::op(...): C++ scalar path, useful as a functionally equivalent path or for broader type support
Most 3-channel images are passed with a cn=3 parameter. A few NEON filter operators have dedicated _3ch fast entries, such as gaussianBlur3x3_3ch, gaussianBlur5x5_3ch, and medianFilter3x3_3ch. The API Reference is the source of truth.
Trial Notes
Trial is not the general API. It exposes only two fixed-parameter entry points:
acl::trial::resizeBilinear2xDown_cppacl::trial::resizeBilinear2xDown_neon
Trial input is fixed to 1920x1280, uint8_t, single-channel, contiguous memory. The 2x downscale output is 960x640. Output carries an "ACL Pack Trial" watermark.
#include <acl/acl.h>
#include <acl/api.h>
#include <cstdint>
uint8_t* src = /* 1920x1280 */;
uint8_t* dst = /* 960x640 */;
int ret = acl::init("license.dat");
if (ret == 0) {
ret = acl::trial::resizeBilinear2xDown_neon(src, dst);
}Error Codes
| Code | Macro | Meaning |
|---|---|---|
0 | ACL_OK | Success |
-1 | ACL_ERR_GENERIC | Unclassified failure |
-2 | ACL_ERR_INVAL | Invalid argument, such as null pointer, bad size, or enum out of range |
-3 | ACL_ERR_NOMEM | Out of memory or temporary workspace allocation failed |
-4 | ACL_ERR_NOSUP | Unsupported type or parameter combination |
-5 | ACL_ERR_IO | File or I/O failure |
-1001 | ACL_ERR_LICENSE_INVALID | License file missing, corrupt, signature check failed, or init has not succeeded |
-1005 | ACL_ERR_NOT_LICENSED | License tier does not match the library, or the operator is not in this tier |
-1006 | ACL_ERR_RESOLUTION_LIMIT | Trial input does not match the fixed size |
Common Issues
| Symptom | Fix |
|---|---|
acl/acl.h: No such file | Check that the include path points to include/ |
undefined reference to acl::init | Make sure you link the libacl.a from the same zip |
Android link errors for __android_log_print, __atomic_*, or zlib symbols | Link log atomic z |
Linux link errors for pthread_* | Link pthread |
Every operator returns -1001 | Check that acl::init() is called first and returns 0 |
acl::init() returns -1005 | license.dat and libacl.a are not from the same tier or delivery package |
Memory And Stride
- Input and output image buffers are allocated and freed by customer code.
strideis in bytes, not pixels.- Pass
0for contiguous memory; pass the real row pitch for padded rows. - For contiguous images, the minimum stride is
width * channels * sizeof(T). - Some operators allocate internal temporary workspace; allocation failure returns
ACL_ERR_NOMEM.
Next: see the API Reference or Operator Tier List.