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.