From dd7c75d0d989835c1437e0cfa071408a23d993cd Mon Sep 17 00:00:00 2001
From: Dana <Dana_Lee1016@126.com>
Date: 星期一, 01 十二月 2025 15:37:54 +0800
Subject: [PATCH] 1.usb添加水印

---
 usbcameralib/CMakeLists.txt              |    9 
 usbcameralib/src/main/cpp/ImageProc.c    |    8 
 usbcameralib/src/main/cpp/watermark.h    |    8 
 usbcameralib/src/main/cpp/apptimer.cpp   |  262 ++++++++++++++++++++++++++
 usbcameralib/src/main/cpp/charencode.cpp |  204 ++++++++++++++++++++
 usbcameralib/build.gradle                |    3 
 usbcameralib/src/main/cpp/apptimer.h     |   69 ++++++
 usbcameralib/src/main/cpp/watermark.cpp  |   26 ++
 8 files changed, 582 insertions(+), 7 deletions(-)

diff --git a/usbcameralib/CMakeLists.txt b/usbcameralib/CMakeLists.txt
index 91b02d6..4ca0632 100644
--- a/usbcameralib/CMakeLists.txt
+++ b/usbcameralib/CMakeLists.txt
@@ -17,10 +17,11 @@
 
         # Provides a relative path to your source file(s).
         src/main/cpp/libyuv.c
+        src/main/cpp/apptimer.cpp
+        src/main/cpp/charencode.cpp
+        src/main/cpp/watermark.cpp
         src/main/cpp/ImageProc.c
-        src/main/cpp/charencode.c
         src/main/cpp/jpeg.c
-        src/main/cpp/watermark.c
         src/main/cpp/SonixCamera/ROMData.c
         src/main/cpp/SonixCamera/SFData.c
         src/main/cpp/SonixCamera/SonixCamera.c
@@ -62,7 +63,9 @@
         jpeg
         turbojpeg
         ${log-lib}
-        ${g-lib})
+        ${g-lib}
+        c++_shared
+)
 
 #target_link_libraries( # Specifies the target library.
 #        usbcamera-lib
diff --git a/usbcameralib/build.gradle b/usbcameralib/build.gradle
index dd4ebe9..de580b6 100644
--- a/usbcameralib/build.gradle
+++ b/usbcameralib/build.gradle
@@ -14,7 +14,7 @@
 
         externalNativeBuild {
             cmake {
-                arguments "-DANDROID_ARM_NEON=TRUE"
+                arguments "-DANDROID_ARM_NEON=TRUE","-DANDROID_STL=c++_shared"
                 cppFlags ""
             }
         }
@@ -43,6 +43,7 @@
         pickFirst 'lib/armeabi-v7a/libturbojpeg.so'
         pickFirst 'lib/arm64-v8a/libjpeg.so'
         pickFirst 'lib/arm64-v8a/libturbojpeg.so'
+        pickFirst 'lib/*/libc++_shared.so'
 
     }
 
diff --git a/usbcameralib/src/main/cpp/ImageProc.c b/usbcameralib/src/main/cpp/ImageProc.c
index b141f9d..0d55c1a 100644
--- a/usbcameralib/src/main/cpp/ImageProc.c
+++ b/usbcameralib/src/main/cpp/ImageProc.c
@@ -1107,6 +1107,11 @@
 		(*env)->ReleaseStringUTFChars(env, name, except_camera_name);
 	}
 
+    if (ret == SUCCESS_LOCAL) {
+        InitWatermark("/system/ms_unicode_24.bin", IMG_WIDTH, IMG_HEIGHT);
+        wm_enable = true;
+    }
+
 	return ret;
 }
 
@@ -1122,6 +1127,9 @@
 	pthread_mutex_lock(&mutex);
     cam_inited = false;
 
+    wm_enable = false;
+    UninitWatermark();
+
     LOGI("stopcapturing");
 	stopcapturing();
 
diff --git a/usbcameralib/src/main/cpp/apptimer.cpp b/usbcameralib/src/main/cpp/apptimer.cpp
new file mode 100644
index 0000000..ff2053a
--- /dev/null
+++ b/usbcameralib/src/main/cpp/apptimer.cpp
@@ -0,0 +1,262 @@
+//
+// Created by YY on 2021/3/16.
+//
+
+#include "apptimer.h"
+//#include "../jni_log.h"
+
+#include <cstdint>
+#include <functional>
+#include <chrono>
+#include <mutex>
+#include <condition_variable>
+#include <list>
+#include <thread>
+#include <map>
+#include <string>
+#include <sstream>
+#include <iomanip>
+
+#define DEBUG(fmt, args...)     //LOGD("<apptimer> <%s>: " fmt, __func__, ##args)
+
+std::mutex mtx;
+
+std::map<void(*)(apptimer_var_t), CTimer *> TimerList;
+
+static void RemoveTimerList(const CTimer *p);
+
+CTimer::CTimer() {
+    flag = 0;
+    var.var_ptr = nullptr;
+    var.var1 = var.var2 = var.var_length = 0;
+    pthread = nullptr;
+}
+
+CTimer::~CTimer() {
+    if (pthread != nullptr) {
+        delete pthread;
+    }
+    if (var.var_ptr != nullptr) {
+        delete var.var_ptr;
+    }
+}
+
+bool CTimer::_updateStatus(CTimer *timer) {
+    if (timer->flag == 0) {
+        return false;
+    } else {
+        return true;    //cancel
+    }
+}
+
+void CTimer::_do_task_func(uint32_t msec, CTimer *timer, std::function<void(apptimer_var_t)> callback) {
+    std::unique_lock<std::mutex> lk(timer->cv_mtx);
+
+    auto now = std::chrono::steady_clock::now();
+
+    if (timer->cv.wait_until(lk, now + std::chrono::milliseconds(msec), std::bind(_updateStatus, timer)) == false) {
+        RemoveTimerList(timer);             // 浠庡垪琛ㄤ腑鍒犻櫎绱㈠紩
+
+        if (timer->flag == 0) {
+            callback(timer->var);
+        }
+    } else {
+//        LOGD("Cancel %d", static_cast<int>(timer->flag));
+        RemoveTimerList(timer);
+    }
+
+    //delete timer;
+    lk.unlock();
+//    std::thread(clear, timer).detach();
+    delete timer;
+}
+
+void CTimer::copy(int value1, int value2, const void *data, int length)
+{
+    this->var.var1 = value1;
+    this->var.var2 = value2;
+    this->var.var_length = length;
+    if (length > 0 && data != nullptr) {
+        this->var.var_ptr = new uint8_t[length];
+        memcpy(this->var.var_ptr, data, length);
+    } else {
+        this->var.var_ptr = nullptr;
+    }
+}
+
+void CTimer::clear(CTimer *timer)
+{
+    if (timer != nullptr) {
+        delete timer;
+    }
+}
+
+bool CTimer::start(uint32_t msec, std::function<void(apptimer_var_t)> callback) {
+    if (pthread == nullptr) {
+        try {
+            pthread = new std::thread(_do_task_func, msec, this, callback);
+            pthread->detach();
+        } catch (std::exception &ex) {
+            DEBUG("%s", ex.what());
+            return false;
+        }
+//        this->callbackThread = std::thread(_do_task_func, msec, this, callback);
+//        this->callbackThread.detach();
+    }
+    return true;
+}
+
+void CTimer::stop() {
+    std::unique_lock<std::mutex> lk(this->cv_mtx);
+    this->flag = 1;
+    this->cv.notify_one();
+}
+
+void AppTimer_init(void)
+{
+    TimerList.clear();
+}
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec)
+{
+    CTimer *cTimer = new CTimer();
+    cTimer->copy(0, 0, nullptr, 0);
+
+    std::lock_guard<std::mutex> lock(mtx);
+    TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer));
+
+    if (cTimer->start(msec, cb) == false) {
+        auto it = TimerList.find(cb);
+        if (it != TimerList.end()) {
+            CTimer *ptr = it->second;
+            TimerList.erase(it);
+        }
+        delete cTimer;
+    }
+}
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, int value1, int value2)
+{
+    CTimer *cTimer = new CTimer();
+    cTimer->copy(value1, value2, nullptr, 0);
+
+    std::lock_guard<std::mutex> lock(mtx);
+    TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer));
+
+    if (cTimer->start(msec, cb) == false) {
+        auto it = TimerList.find(cb);
+        if (it != TimerList.end()) {
+            CTimer *ptr = it->second;
+            TimerList.erase(it);
+        }
+        delete cTimer;
+    }
+}
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, void *data, int lenght)
+{
+    CTimer *cTimer = new CTimer();
+    cTimer->copy(0, 0, data, lenght);
+
+    std::lock_guard<std::mutex> lock(mtx);
+    TimerList.insert(std::pair<void (*)(apptimer_var_t), CTimer *>(cb, cTimer));
+
+    if (cTimer->start(msec, cb) == false) {
+        auto it = TimerList.find(cb);
+        if (it != TimerList.end()) {
+            CTimer *ptr = it->second;
+            TimerList.erase(it);
+        }
+        delete cTimer;
+    }
+}
+
+void AppTimer_delete(void(*cb)(apptimer_var_t))
+{
+    std::lock_guard<std::mutex> lock(mtx);
+
+    auto it = TimerList.find(cb);
+    if (it != TimerList.end()) {
+        CTimer *ptr = it->second;
+        TimerList.erase(it);
+        ptr->stop();
+    }
+}
+
+static void RemoveTimerList(const CTimer *p)
+{
+    std::lock_guard<std::mutex> lock(mtx);
+
+    for (auto it = TimerList.begin(); it != TimerList.end(); ++it) {
+        CTimer *ptr = it->second;
+        if (ptr == p) {
+            TimerList.erase(it);
+            break;
+        }
+    }
+}
+
+uint32_t AppTimer_GetTickCount(void)
+{
+    std::chrono::milliseconds as = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch());
+
+    return as.count();
+}
+
+uint64_t AppTimer_GetGmtTickCount(void)
+{
+    std::chrono::milliseconds as = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
+
+    return as.count();
+}
+
+std::string FormatTime(const char *fmt)
+{
+    auto now = std::chrono::system_clock::now();
+    auto timet = std::chrono::system_clock::to_time_t(now);
+    auto localTime = *std::localtime(&timet);
+
+    std::stringstream ss;
+    std::string str;
+    ss << std::put_time(&localTime, "%Y-%m-%d %H:%M:%S");
+    str = ss.str();
+    return str;
+}
+
+std::time_t MktimeString(const char *str, const char *fmt)
+{
+    struct std::tm dt;
+    std::istringstream ss(str);
+
+    ss >> std::get_time(&dt, fmt);
+
+    std::stringstream out;
+    out << std::put_time(&dt, "%Y-%m-%d %H:%M:%S");
+//    DEBUG("%s, %ld", out.str().c_str(), std::mktime(&dt));
+
+    time_t utc = std::mktime(&dt);
+
+    return utc;
+}
+
+time_t TimeStamp(int year, int mon, int day, int hour, int min, int sec)
+{
+    // YYHHDDhhmmss(GMT+8)
+    struct tm test_tm;
+
+    struct timeval tv;
+    struct timezone tz;
+
+    gettimeofday(&tv,&tz);
+
+    memset(&test_tm, 0, sizeof(test_tm));
+
+    test_tm.tm_year = year - 1900;
+    test_tm.tm_mon = mon - 1;
+    test_tm.tm_mday = day;
+    test_tm.tm_hour = hour;
+    test_tm.tm_min = min;
+    test_tm.tm_sec = sec;
+
+    return mktime(&test_tm) - tz.tz_minuteswest*60;
+}
diff --git a/usbcameralib/src/main/cpp/apptimer.h b/usbcameralib/src/main/cpp/apptimer.h
new file mode 100644
index 0000000..ce8881c
--- /dev/null
+++ b/usbcameralib/src/main/cpp/apptimer.h
@@ -0,0 +1,69 @@
+//
+// Created by YY on 2021/3/16.
+//
+
+#ifndef NDKADV_APPTIMER_H
+#define NDKADV_APPTIMER_H
+
+#include <cstdint>
+#include <functional>
+#include <thread>
+#include <chrono>
+#include <atomic>
+#include <mutex>
+#include <condition_variable>
+#include <string>
+#include <ctime>
+
+#define D_SEC(n)		((n)*1000UL)
+#define D_MIN(n)		((n)*1000UL*60UL)
+#define D_HOUR(n)		((n)*1000UL*60UL*60UL)
+
+typedef struct {
+    int var1;
+    int var2;
+    void * var_ptr;
+    int var_length;
+} apptimer_var_t;
+
+class CTimer {
+public:
+    CTimer();
+    virtual ~CTimer();
+    static bool _updateStatus(CTimer *timer);
+    static void _do_task_func(uint32_t msec, CTimer *timer, std::function<void(apptimer_var_t)> callback);
+    bool start(uint32_t msec, std::function<void(apptimer_var_t)> callback);
+    void stop();
+    void copy(int value1, int value2, const void *data, int length);
+    static void clear(CTimer *timer);
+private:
+    std::mutex cv_mtx;
+    std::condition_variable cv;
+//    std::thread callbackThread;
+    std::thread *pthread;
+    apptimer_var_t var;
+public:
+    std::atomic_int flag;
+};
+
+void AppTimer_init(void);
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec);
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, int value1, int value2);
+
+void AppTimer_add(void(*cb)(apptimer_var_t), uint32_t msec, void *data, int lenght);
+
+void AppTimer_delete(void (*cb) (apptimer_var_t));
+
+uint32_t AppTimer_GetTickCount(void);
+
+uint64_t AppTimer_GetGmtTickCount(void);
+
+std::string FormatTime(const char *fmt = "%Y-%m-%d %H:%M:%S");
+
+std::time_t MktimeString(const char *str, const char *fmt);
+
+time_t TimeStamp(int year, int mon, int day, int hour, int min, int sec);
+
+#endif //NDKADV_APPTIMER_H
diff --git a/usbcameralib/src/main/cpp/charencode.cpp b/usbcameralib/src/main/cpp/charencode.cpp
new file mode 100644
index 0000000..b29753e
--- /dev/null
+++ b/usbcameralib/src/main/cpp/charencode.cpp
@@ -0,0 +1,204 @@
+//
+// Created by YY on 2021/10/22.
+//
+
+#include <stdlib.h>
+#include "charencode.h"
+
+/*****************************************************************************
+ * 灏嗕竴涓瓧绗︾殑Unicode(UCS-2鍜孶CS-4)缂栫爜杞崲鎴怳TF-8缂栫爜.
+ *
+ * 鍙傛暟:
+ *    unic     瀛楃鐨刄nicode缂栫爜鍊�
+ *    pOutput  鎸囧悜杈撳嚭鐨勭敤浜庡瓨鍌║TF8缂栫爜鍊肩殑缂撳啿鍖虹殑鎸囬拡
+ *    outsize  pOutput缂撳啿鐨勫ぇ灏�
+ *
+ * 杩斿洖鍊�:
+ *    杩斿洖杞崲鍚庣殑瀛楃鐨刄TF8缂栫爜鎵�鍗犵殑瀛楄妭鏁�, 濡傛灉鍑洪敊鍒欒繑鍥� 0 .
+ *
+ * 娉ㄦ剰:
+ *     1. UTF8娌℃湁瀛楄妭搴忛棶棰�, 浣嗘槸Unicode鏈夊瓧鑺傚簭瑕佹眰;
+ *        瀛楄妭搴忓垎涓哄ぇ绔�(Big Endian)鍜屽皬绔�(Little Endian)涓ょ;
+ *        鍦↖ntel澶勭悊鍣ㄤ腑閲囩敤灏忕娉曡〃绀�, 鍦ㄦ閲囩敤灏忕娉曡〃绀�. (浣庡湴鍧�瀛樹綆浣�)
+ *     2. 璇蜂繚璇� pOutput 缂撳啿鍖烘湁鏈�灏戞湁 6 瀛楄妭鐨勭┖闂村ぇ灏�!
+ ****************************************************************************/
+int enc_unicode_to_utf8_one(unsigned long unic, unsigned char *pOutput,
+                            int outSize)
+{
+	if (pOutput == NULL || outSize < 6)
+        return 0;
+
+    if (unic <= 0x0000007F)
+    {
+        // * U-00000000 - U-0000007F:  0xxxxxxx
+        *pOutput = (unic & 0x7F);
+        return 1;
+    }
+    else if (unic >= 0x00000080 && unic <= 0x000007FF)
+    {
+        // * U-00000080 - U-000007FF:  110xxxxx 10xxxxxx
+        *(pOutput + 1) = (unic & 0x3F) | 0x80;
+        *pOutput = ((unic >> 6) & 0x1F) | 0xC0;
+        return 2;
+    }
+    else if (unic >= 0x00000800 && unic <= 0x0000FFFF)
+    {
+        // * U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
+        *(pOutput + 2) = (unic & 0x3F) | 0x80;
+        *(pOutput + 1) = ((unic >> 6) & 0x3F) | 0x80;
+        *pOutput = ((unic >> 12) & 0x0F) | 0xE0;
+        return 3;
+    }
+    else if (unic >= 0x00010000 && unic <= 0x001FFFFF)
+    {
+        // * U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
+        *(pOutput + 3) = (unic & 0x3F) | 0x80;
+        *(pOutput + 2) = ((unic >> 6) & 0x3F) | 0x80;
+        *(pOutput + 1) = ((unic >> 12) & 0x3F) | 0x80;
+        *pOutput = ((unic >> 18) & 0x07) | 0xF0;
+        return 4;
+    }
+    else if (unic >= 0x00200000 && unic <= 0x03FFFFFF)
+    {
+        // * U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+        *(pOutput + 4) = (unic & 0x3F) | 0x80;
+        *(pOutput + 3) = ((unic >> 6) & 0x3F) | 0x80;
+        *(pOutput + 2) = ((unic >> 12) & 0x3F) | 0x80;
+        *(pOutput + 1) = ((unic >> 18) & 0x3F) | 0x80;
+        *pOutput = ((unic >> 24) & 0x03) | 0xF8;
+        return 5;
+    }
+    else if (unic >= 0x04000000 && unic <= 0x7FFFFFFF)
+    {
+        // * U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
+        *(pOutput + 5) = (unic & 0x3F) | 0x80;
+        *(pOutput + 4) = ((unic >> 6) & 0x3F) | 0x80;
+        *(pOutput + 3) = ((unic >> 12) & 0x3F) | 0x80;
+        *(pOutput + 2) = ((unic >> 18) & 0x3F) | 0x80;
+        *(pOutput + 1) = ((unic >> 24) & 0x3F) | 0x80;
+        *pOutput = ((unic >> 30) & 0x01) | 0xFC;
+        return 6;
+    }
+
+    return 0;
+}
+
+/*****************************************************************************
+ * 灏嗕竴涓瓧绗︾殑UTF8缂栫爜杞崲鎴怳nicode(UCS-2鍜孶CS-4)缂栫爜.
+ *
+ * 鍙傛暟:
+ *    pInput      鎸囧悜杈撳叆缂撳啿鍖�, 浠TF-8缂栫爜
+ *    Unic        鎸囧悜杈撳嚭缂撳啿鍖�, 鍏朵繚瀛樼殑鏁版嵁鍗虫槸Unicode缂栫爜鍊�,
+ *                绫诲瀷涓簎nsigned long .
+ *
+ * 杩斿洖鍊�:
+ *    鎴愬姛鍒欒繑鍥炶瀛楃鐨刄TF8缂栫爜鎵�鍗犵敤鐨勫瓧鑺傛暟; 澶辫触鍒欒繑鍥�0.
+ *
+ * 娉ㄦ剰:
+ *     1. UTF8娌℃湁瀛楄妭搴忛棶棰�, 浣嗘槸Unicode鏈夊瓧鑺傚簭瑕佹眰;
+ *        瀛楄妭搴忓垎涓哄ぇ绔�(Big Endian)鍜屽皬绔�(Little Endian)涓ょ;
+ *        鍦↖ntel澶勭悊鍣ㄤ腑閲囩敤灏忕娉曡〃绀�, 鍦ㄦ閲囩敤灏忕娉曡〃绀�. (浣庡湴鍧�瀛樹綆浣�)
+ ****************************************************************************/
+int enc_utf8_to_unicode_one(const unsigned char* pInput, unsigned long *Unic)
+{
+    if (pInput == NULL || Unic == NULL)
+        return 0;
+
+    // b1 琛ㄧずUTF-8缂栫爜鐨刾Input涓殑楂樺瓧鑺�, b2 琛ㄧず娆¢珮瀛楄妭, ...
+    char b1, b2, b3, b4, b5, b6;
+
+    *Unic = 0x0; // 鎶� *Unic 鍒濆鍖栦负鍏ㄩ浂
+    int utfbytes = enc_get_utf8_size(*pInput);
+    unsigned char *pOutput = (unsigned char *)Unic;
+
+    switch (utfbytes)
+    {
+        case 0:
+            *pOutput = *pInput;
+            utfbytes += 1;
+            break;
+        case 2:
+            b1 = *pInput;
+            b2 = *(pInput + 1);
+            if ((b2 & 0xE0) != 0x80)
+                return 0;
+            *pOutput = (b1 << 6) + (b2 & 0x3F);
+            *(pOutput + 1) = (b1 >> 2) & 0x07;
+            break;
+        case 3:
+            b1 = *pInput;
+            b2 = *(pInput + 1);
+            b3 = *(pInput + 2);
+            if (((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80))
+                return 0;
+            *pOutput = (b2 << 6) + (b3 & 0x3F);
+            *(pOutput + 1) = (b1 << 4) + ((b2 >> 2) & 0x0F);
+            break;
+        case 4:
+            b1 = *pInput;
+            b2 = *(pInput + 1);
+            b3 = *(pInput + 2);
+            b4 = *(pInput + 3);
+            if (((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
+                || ((b4 & 0xC0) != 0x80))
+                return 0;
+            *pOutput = (b3 << 6) + (b4 & 0x3F);
+            *(pOutput + 1) = (b2 << 4) + ((b3 >> 2) & 0x0F);
+            *(pOutput + 2) = ((b1 << 2) & 0x1C) + ((b2 >> 4) & 0x03);
+            break;
+        case 5:
+            b1 = *pInput;
+            b2 = *(pInput + 1);
+            b3 = *(pInput + 2);
+            b4 = *(pInput + 3);
+            b5 = *(pInput + 4);
+            if (((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
+                || ((b4 & 0xC0) != 0x80) || ((b5 & 0xC0) != 0x80))
+                return 0;
+            *pOutput = (b4 << 6) + (b5 & 0x3F);
+            *(pOutput + 1) = (b3 << 4) + ((b4 >> 2) & 0x0F);
+            *(pOutput + 2) = (b2 << 2) + ((b3 >> 4) & 0x03);
+            *(pOutput + 3) = (b1 << 6);
+            break;
+        case 6:
+            b1 = *pInput;
+            b2 = *(pInput + 1);
+            b3 = *(pInput + 2);
+            b4 = *(pInput + 3);
+            b5 = *(pInput + 4);
+            b6 = *(pInput + 5);
+            if (((b2 & 0xC0) != 0x80) || ((b3 & 0xC0) != 0x80)
+                || ((b4 & 0xC0) != 0x80) || ((b5 & 0xC0) != 0x80)
+                || ((b6 & 0xC0) != 0x80))
+                return 0;
+            *pOutput = (b5 << 6) + (b6 & 0x3F);
+            *(pOutput + 1) = (b5 << 4) + ((b6 >> 2) & 0x0F);
+            *(pOutput + 2) = (b3 << 2) + ((b4 >> 4) & 0x03);
+            *(pOutput + 3) = ((b1 << 6) & 0x40) + (b2 & 0x3F);
+            break;
+        default:
+            return 0;
+            break;
+    }
+
+    return utfbytes;
+}
+
+int enc_get_utf8_size(const unsigned char pInput)
+{
+    unsigned char c = pInput;
+    // 0xxxxxxx 杩斿洖0
+    // 10xxxxxx 涓嶅瓨鍦�
+    // 110xxxxx 杩斿洖2
+    // 1110xxxx 杩斿洖3
+    // 11110xxx 杩斿洖4
+    // 111110xx 杩斿洖5
+    // 1111110x 杩斿洖6
+    if(c< 0x80) return 0;
+    if(c>=0x80 && c<0xC0) return -1;
+    if(c>=0xC0 && c<0xE0) return 2;
+    if(c>=0xE0 && c<0xF0) return 3;
+    if(c>=0xF0 && c<0xF8) return 4;
+    if(c>=0xF8 && c<0xFC) return 5;
+    if(c>=0xFC) return 6;
+}
diff --git a/usbcameralib/src/main/cpp/watermark.c b/usbcameralib/src/main/cpp/watermark.cpp
similarity index 90%
rename from usbcameralib/src/main/cpp/watermark.c
rename to usbcameralib/src/main/cpp/watermark.cpp
index b15d9f6..1a73e64 100644
--- a/usbcameralib/src/main/cpp/watermark.c
+++ b/usbcameralib/src/main/cpp/watermark.cpp
@@ -12,6 +12,7 @@
 #include "watermark.h"
 #include "charencode.h"
 #include "ImageProc.h"
+#include "apptimer.h"
 
 //static pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
 typedef enum {
@@ -33,6 +34,22 @@
 static int pic_width = 0, pic_height = 0;
 static color_t wm_color;
 
+static void PrintTime(apptimer_var_t val)
+{
+    text_t text;
+
+    text.x = 10;
+    text.y = 10;
+
+    memset(text.text, 0, sizeof (text.text));
+
+    strcpy(text.text, FormatTime().c_str());
+
+    PrepareWatermark(RED, 24, 2, 1, &text);
+
+    AppTimer_add(PrintTime, D_SEC(1));
+}
+
 void InitWatermark(const char *font, int width, int height)
 {
     LOGI("InitWatermark");
@@ -48,6 +65,8 @@
 
     pic_width = width;
     pic_height = height;
+
+    AppTimer_add(PrintTime, D_SEC(1));
 }
 
 void UninitWatermark(void)
@@ -58,6 +77,7 @@
         wm = NULL;
     }
     wm_num = 0;
+    AppTimer_delete(PrintTime);
 }
 
 void PrepareWatermark(int color, int font_size, int multiple, int num, const text_t *texts)
@@ -75,7 +95,7 @@
     const int bytes_per_line = font_size / 8;
 
     wm_num = 0;
-    wm_color = color;
+    wm_color = static_cast<color_t>(color);
 
     //FILE *fp = fopen("/storage/self/primary/ms_unicode.bin", "rb");
     //FILE *fp = fopen("/system/ms_unicode.bin", "rb");
@@ -86,14 +106,14 @@
         uint8_t zm[64*64/8];        // 鏈�澶�
 
         for (int m = 0; m < num; ++m) {
-            char *str = texts[m].text;
+            const char *str = texts[m].text;
 
             int screen_x = texts[m].x;
             int screen_y = texts[m].y;
             offset = 0;
 
             while (str != NULL && offset < strlen(str)) {
-                int skip = enc_utf8_to_unicode_one(str + offset, &unicode);
+                int skip = enc_utf8_to_unicode_one(reinterpret_cast<const unsigned char *>(str + offset), &unicode);
                 int next_x = 0;
 
                 if (skip == 0) {
diff --git a/usbcameralib/src/main/cpp/watermark.h b/usbcameralib/src/main/cpp/watermark.h
index 8f49b90..a0649d0 100644
--- a/usbcameralib/src/main/cpp/watermark.h
+++ b/usbcameralib/src/main/cpp/watermark.h
@@ -5,6 +5,10 @@
 #ifndef FLOATWINDOWVEDIO_WATERMARK_H
 #define FLOATWINDOWVEDIO_WATERMARK_H
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 typedef struct {
     int x;
     int y;
@@ -19,4 +23,8 @@
 
 void AddWatermark(uint8_t *mem);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif //FLOATWINDOWVEDIO_WATERMARK_H

--
Gitblit v1.8.0