Skip to content

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:

text
your_project/
  include/acl/
    acl.h
    api.h
    err.h
    typeDef.h
  lib/arm64-v8a/
    libacl.a
  license.dat

Linux aarch64:

text
your_project/
  include/acl/
    acl.h
    api.h
    err.h
    typeDef.h
  lib/linux-aarch64/
    libacl.a
  license.dat

Trial 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
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:

makefile
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:

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
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:

bash
cmake -DCMAKE_TOOLCHAIN_FILE=toolchains/linux-aarch64.cmake -DCMAKE_BUILD_TYPE=Release -S . -B build
cmake --build build -j

Without CMake, a direct cross-compile command also works:

bash
aarch64-linux-gnu-g++ -O2 -std=c++17 -Iinclude \
    -o your_app your_app.cpp lib/linux-aarch64/libacl.a \
    -lm -lpthread

3. Initialize License

Call acl::init() once before any operator call. Pass the real path to license.dat on the device.

cpp
#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:

java
File licenseFile = new File(context.getFilesDir(), "license.dat");
int ret = nativeInitAcl(licenseFile.getAbsolutePath());

JNI side:

cpp
#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>:

cpp
#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 ARM64
  • acl::{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_cpp
  • acl::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.

cpp
#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

CodeMacroMeaning
0ACL_OKSuccess
-1ACL_ERR_GENERICUnclassified failure
-2ACL_ERR_INVALInvalid argument, such as null pointer, bad size, or enum out of range
-3ACL_ERR_NOMEMOut of memory or temporary workspace allocation failed
-4ACL_ERR_NOSUPUnsupported type or parameter combination
-5ACL_ERR_IOFile or I/O failure
-1001ACL_ERR_LICENSE_INVALIDLicense file missing, corrupt, signature check failed, or init has not succeeded
-1005ACL_ERR_NOT_LICENSEDLicense tier does not match the library, or the operator is not in this tier
-1006ACL_ERR_RESOLUTION_LIMITTrial input does not match the fixed size

Common Issues

SymptomFix
acl/acl.h: No such fileCheck that the include path points to include/
undefined reference to acl::initMake sure you link the libacl.a from the same zip
Android link errors for __android_log_print, __atomic_*, or zlib symbolsLink log atomic z
Linux link errors for pthread_*Link pthread
Every operator returns -1001Check that acl::init() is called first and returns 0
acl::init() returns -1005license.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.
  • stride is in bytes, not pixels.
  • Pass 0 for 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.