├── dist ├── 5 │ ├── x86 │ │ └── ascreencap │ ├── x86_64 │ │ └── ascreencap │ ├── arm64-v8a │ │ └── ascreencap │ └── armeabi-v7a │ │ └── ascreencap ├── 8 │ ├── x86 │ │ └── ascreencap │ ├── x86_64 │ │ └── ascreencap │ ├── arm64-v8a │ │ └── ascreencap │ └── armeabi-v7a │ │ └── ascreencap └── 9 │ ├── x86 │ └── ascreencap │ ├── x86_64 │ └── ascreencap │ ├── arm64-v8a │ └── ascreencap │ └── armeabi-v7a │ └── ascreencap ├── fakelib ├── Application.mk ├── vs-libsigchain.txt ├── vs-libart.txt ├── libfake.h ├── include │ ├── libfake.h │ ├── libsigchain.h │ ├── JniInvocation.h │ └── SurfaceComposerClient_a5_9.h ├── README-libart.md ├── libart.cpp ├── libutils.cpp ├── libbinder.cpp ├── Android.mk ├── libui.cpp └── libgui.cpp ├── Application.mk ├── .gitignore ├── ascreencap-AScreenConf.h ├── version.h ├── ascreencap-AScreenCap.h ├── LICENSE ├── Android.mk ├── ascreencap.h ├── Build-all.cmd ├── ascreencap-ABitmapLite.h ├── Makefile ├── ascreencap.cpp ├── AScreencap.cbp ├── README.md ├── ascreencap-AScreenConf.cpp ├── ascreencap-AScreenCap.cpp ├── extern ├── argh.h └── lz4 │ └── lz4.h └── ascreencap-ABitmapLite.cpp /dist/5/x86/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/5/x86/ascreencap -------------------------------------------------------------------------------- /dist/8/x86/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/8/x86/ascreencap -------------------------------------------------------------------------------- /dist/9/x86/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/9/x86/ascreencap -------------------------------------------------------------------------------- /dist/5/x86_64/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/5/x86_64/ascreencap -------------------------------------------------------------------------------- /dist/8/x86_64/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/8/x86_64/ascreencap -------------------------------------------------------------------------------- /dist/9/x86_64/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/9/x86_64/ascreencap -------------------------------------------------------------------------------- /dist/5/arm64-v8a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/5/arm64-v8a/ascreencap -------------------------------------------------------------------------------- /dist/8/arm64-v8a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/8/arm64-v8a/ascreencap -------------------------------------------------------------------------------- /dist/9/arm64-v8a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/9/arm64-v8a/ascreencap -------------------------------------------------------------------------------- /dist/5/armeabi-v7a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/5/armeabi-v7a/ascreencap -------------------------------------------------------------------------------- /dist/8/armeabi-v7a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/8/armeabi-v7a/ascreencap -------------------------------------------------------------------------------- /dist/9/armeabi-v7a/ascreencap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ClnViewer/Android-fast-screen-capture/HEAD/dist/9/armeabi-v7a/ascreencap -------------------------------------------------------------------------------- /fakelib/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := all 2 | APP_STL := c++_static 3 | APP_PLATFORM := android-21 4 | APP_BUILD_SCRIPT := Android.mk 5 | -------------------------------------------------------------------------------- /Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi-v7a 2 | APP_STL := c++_static 3 | APP_BUILD_SCRIPT := Android.mk 4 | APP_PLATFORM := android-21 5 | APP_BUILD_VERSION := 5 6 | -------------------------------------------------------------------------------- /fakelib/vs-libsigchain.txt: -------------------------------------------------------------------------------- 1 | { 2 | global: 3 | ClaimSignalChain; 4 | UnclaimSignalChain; 5 | InvokeUserSignalHandler; 6 | InitializeSignalChain; 7 | EnsureFrontOfChain; 8 | SetSpecialSignalHandlerFn; 9 | AddSpecialSignalHandlerFn; 10 | RemoveSpecialSignalHandlerFn; 11 | local: 12 | *; 13 | }; 14 | -------------------------------------------------------------------------------- /fakelib/vs-libart.txt: -------------------------------------------------------------------------------- 1 | { 2 | global: 3 | ClaimSignalChain; 4 | UnclaimSignalChain; 5 | InvokeUserSignalHandler; 6 | InitializeSignalChain; 7 | EnsureFrontOfChain; 8 | SetSpecialSignalHandlerFn; 9 | AddSpecialSignalHandlerFn; 10 | RemoveSpecialSignalHandlerFn; 11 | JNI_GetDefaultJavaVMInitArgs; 12 | JNI_CreateJavaVM; 13 | JNI_GetCreatedJavaVMs; 14 | local: 15 | *; 16 | }; 17 | -------------------------------------------------------------------------------- /fakelib/libfake.h: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(__ANDROID__) 3 | #error "__ANDROID__ build only !" 4 | #endif 5 | 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #define LOG(...) fprintf(stderr, __VA_ARGS__) 15 | 16 | namespace android { 17 | 18 | template class sp { 19 | public: 20 | T* m_ptr; 21 | }; 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /fakelib/include/libfake.h: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(__ANDROID__) 3 | #error "__ANDROID__ build only !" 4 | #endif 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define LOG(...) fprintf(stderr, __VA_ARGS__) 13 | #define ATTR_UNUSED __attribute__ (( __unused__ )) 14 | 15 | namespace android { 16 | 17 | template class sp { 18 | public: 19 | T* m_ptr; 20 | }; 21 | 22 | } 23 | 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | utils/* 3 | libs/* 4 | obj/* 5 | *.save 6 | *.bmarks 7 | *.layout 8 | *.depend 9 | 10 | .svn 11 | # Prerequisites 12 | *.d 13 | 14 | # Compiled Object files 15 | *.slo 16 | *.lo 17 | *.o 18 | *.obj 19 | 20 | # Precompiled Headers 21 | *.gch 22 | *.pch 23 | 24 | # Compiled Dynamic libraries 25 | *.so 26 | *.dylib 27 | *.dll 28 | 29 | # Fortran module files 30 | *.mod 31 | *.smod 32 | 33 | # Compiled Static libraries 34 | *.lai 35 | *.la 36 | *.a 37 | *.lib 38 | 39 | # Executables 40 | *.exe 41 | *.out 42 | *.app 43 | *.sh 44 | *.cmd 45 | -------------------------------------------------------------------------------- /fakelib/README-libart.md: -------------------------------------------------------------------------------- 1 | 2 | ### About use fake stub library `libart` 3 | 4 | - include `include/libsigchain.h` to Application! (weak symbol, needed to original libart.so) 5 | - edit build options from you application and add to LDFLAGS: 6 | - `-Wl,--export-dynamic` and 7 | - `-Wl,--version-script,fakelib/vs-libsigchain.txt` 8 | - build you application 9 | - check app compiled symbol: `readelf -sW youApp >youApp.list; cat youApp.list;` 10 | - check stub library compiled symbol: `readelf -sW libart.so >libart.list; cat libart.list;` 11 | 12 | > 13 | >Note: Version-script file vs-libart.txt only to compile fake stub libart.so 14 | > 15 | 16 | -------------------------------------------------------------------------------- /ascreencap-AScreenConf.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace ACapture 4 | { 5 | 6 | class AScreenConf 7 | { 8 | private: 9 | std::atomic _err; 10 | 11 | public: 12 | bool IsCapStream; 13 | bool IsCapFile; 14 | bool IsCapStdOut; 15 | bool IsCapRatio; 16 | bool IsCapRotate; 17 | bool IsCapPack; 18 | bool IsSDL2Compatible; 19 | bool IsHelp; 20 | bool IsInfo; 21 | uint32_t Ratio; 22 | uint32_t Rotate; 23 | uint32_t FastPack; 24 | std::string FileName; 25 | 26 | AScreenConf(int32_t argc, char **argv); 27 | 28 | void printHelp(); 29 | void printInfo(); 30 | 31 | }; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /fakelib/libart.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "libfake.h" 3 | #include 4 | 5 | /// see README-libart.md for details.. 6 | 7 | # define FUNWEAK __attribute__ ((weak)) 8 | # include "libsigchain.h" 9 | 10 | extern "C" JNIEXPORT jint JNI_GetDefaultJavaVMInitArgs(void *v) 11 | { 12 | LOG("JNI_GetDefaultJavaVMInitArgs(*)\n"); 13 | v = nullptr; 14 | return 0; 15 | } 16 | extern "C" JNIEXPORT jint JNI_CreateJavaVM(JavaVM **jv, JNIEnv **ev, void *v) 17 | { 18 | LOG("JNI_CreateJavaVM(*)\n"); 19 | jv = nullptr; 20 | ev = nullptr; 21 | jint *ji = static_cast(v); 22 | *ji = 0; 23 | return 0; 24 | } 25 | extern "C" JNIEXPORT jint JNI_GetCreatedJavaVMs(JavaVM **jv, jsize jsz, jsize *pjsz) 26 | { 27 | LOG("JNI_GetCreatedJavaVMs(*)\n"); 28 | (void) jsz; 29 | jv = nullptr; 30 | *pjsz = 0; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_H 2 | #define VERSION_H 3 | 4 | //Date Version Types 5 | #define ACAP_DATE "26" 6 | #define ACAP_MONTH "07" 7 | #define ACAP_YEAR "2019" 8 | #define ACAP_UBUNTU_VERSION_STYLE "19.07" 9 | 10 | //Software Status 11 | #define ACAP_STATUS "" 12 | #define ACAP_STATUS_SHORT "" 13 | 14 | //Standard Version Type 15 | #define ACAP_MAJOR 0 16 | #define ACAP_MINOR 0 17 | #define ACAP_BUILD 1 18 | #define ACAP_REVISION 5 19 | 20 | //Miscellaneous Version Types 21 | #define ACAP_BUILDS_COUNT 0 22 | #define ACAP_RC_FILEVERSION 0,0,1,5 23 | #define ACAP_RC_FILEVERSION_STRING "0, 0, 1, 5\0" 24 | #define ACAP_FULLVERSION_STRING "0.0.1.5" 25 | 26 | //SVN Version 27 | #define ACAP_SVN_REVISION "104" 28 | #define ACAP_SVN_DATE "2019-06-07T10:03:15.190172Z" 29 | 30 | //These values are to keep track of your versioning state, don't modify them. 31 | #define ACAP_BUILD_HISTORY 1 32 | 33 | 34 | #endif //VERSION_H 35 | -------------------------------------------------------------------------------- /ascreencap-AScreenCap.h: -------------------------------------------------------------------------------- 1 | 2 | 3 | namespace ACapture 4 | { 5 | 6 | class AScreenCap 7 | { 8 | private: 9 | ACapture::ABitmapLite _adata; 10 | # if (__ANDROID_VER__ >= 9) 11 | android::sp _sc; 12 | # else 13 | android::ScreenshotClient _sc; 14 | # endif 15 | android::sp _dsp; 16 | std::atomic _err; 17 | std::atomic _ready; 18 | 19 | bool getLoop(); 20 | bool sysCap(); 21 | 22 | public: 23 | AScreenCap(); 24 | ~AScreenCap(); 25 | 26 | void setRatio(uint32_t); 27 | void setRotate(uint32_t); 28 | void setNohead(bool); 29 | int32_t getError() const; 30 | void getStream(int32_t); 31 | bool getScreen(); 32 | bool saveFile(std::string const &, bool, int32_t); 33 | bool printStdout(bool, int32_t); 34 | 35 | }; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 NewView 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /fakelib/include/libsigchain.h: -------------------------------------------------------------------------------- 1 | 2 | #if !defined(__LIBSIGNAL_H_) 3 | #define __LIBSIGNAL_H_ 1 4 | 5 | # if !defined(JNIEXPORT) 6 | # define JNIEXPORT __attribute__ ((visibility ("default"))) 7 | # endif 8 | # if !defined(FUNWEAK) 9 | # define FUNWEAK 10 | # endif 11 | # define ATTR_UNUSED __attribute__ (( __unused__ )) 12 | 13 | namespace art { 14 | 15 | static constexpr uint64_t SIGCHAIN_ALLOW_NORETURN = 0x1UL; 16 | 17 | extern "C" FUNWEAK void ClaimSignalChain(int s ATTR_UNUSED, void* v ATTR_UNUSED) {} 18 | extern "C" FUNWEAK void UnclaimSignalChain(int s ATTR_UNUSED) {} 19 | extern "C" FUNWEAK void InvokeUserSignalHandler(int s ATTR_UNUSED, void* i ATTR_UNUSED, void* v ATTR_UNUSED) {} 20 | extern "C" FUNWEAK void InitializeSignalChain() {} 21 | extern "C" FUNWEAK void EnsureFrontOfChain(int s ATTR_UNUSED, void* v ATTR_UNUSED) {} 22 | extern "C" FUNWEAK void SetSpecialSignalHandlerFn(int s ATTR_UNUSED, bool (*fn)(int, void*, void*) ATTR_UNUSED) {} 23 | extern "C" FUNWEAK void AddSpecialSignalHandlerFn(int s ATTR_UNUSED, void* v ATTR_UNUSED) {} 24 | extern "C" FUNWEAK void RemoveSpecialSignalHandlerFn(int s ATTR_UNUSED, bool (*fn)(int, void*, void*) ATTR_UNUSED) {} 25 | 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /fakelib/libutils.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "libfake.h" 3 | 4 | namespace android { 5 | 6 | class RefBase 7 | { 8 | public: 9 | void incStrong(const void* id) const; 10 | void decStrong(const void* id) const; 11 | void forceIncStrong(const void* id) const; 12 | int32_t getStrongCount() const; 13 | 14 | 15 | typedef RefBase basetype; 16 | 17 | protected: 18 | RefBase(); 19 | virtual ~RefBase(); 20 | 21 | enum { 22 | OBJECT_LIFETIME_STRONG = 0x0000, 23 | OBJECT_LIFETIME_WEAK = 0x0001, 24 | OBJECT_LIFETIME_MASK = 0x0001 25 | }; 26 | 27 | }; 28 | 29 | RefBase::RefBase() { 30 | LOG("RefBase::RefBase()\n"); 31 | } 32 | RefBase::~RefBase() { 33 | LOG("RefBase::~RefBase()\n"); 34 | } 35 | void RefBase::incStrong(const void* id) const { 36 | LOG("RefBase::incStrong()\n"); 37 | } 38 | void RefBase::decStrong(const void* id) const { 39 | LOG("RefBase::decStrong()\n"); 40 | } 41 | void RefBase::forceIncStrong(const void* id) const { 42 | LOG("RefBase::forceIncStrong()\n"); 43 | } 44 | int32_t RefBase::getStrongCount() const { 45 | LOG("RefBase::getStrongCount()\n"); 46 | return 0; 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_MODULE := ascreencap 4 | LOCAL_CPP_EXTENSION := .cpp 5 | LOCAL_SRC_FILES := ascreencap-ABitmapLite.cpp ascreencap-AScreenCap.cpp ascreencap-AScreenConf.cpp ascreencap.cpp extern/lz4/lz4.c 6 | LOCAL_CFLAGS := -Wall -Wno-unknown-pragmas -fopenmp -fexceptions -D_DEBUG_X=1 -D_DEBUG_RAW_FILE_X -D__ANDROID_VER__=$(APP_BUILD_VERSION) -D__ANDROID_API_PLATFORM__="$(TARGET_PLATFORM)" 7 | LOCAL_CPPFLAGS := -std=c++17 8 | LOCAL_LDFLAGS := -L./fakelib/libs/$(APP_BUILD_VERSION)/$(TARGET_ARCH_ABI) -Wl,--gc-sections 9 | LOCAL_LDLIBS := -lutils -lgui -lui -lbinder -lomp -llog 10 | LOCAL_C_INCLUDES := fakelib/include C:/__BuildSource/__LIB__/android-aosp-header/android-6.0.0_r1/system/core/include C:/__BuildSource/__LIB__/android-aosp-header/android-6.0.0_r1/frameworks/base/include C:/__BuildSource/__LIB__/android-aosp-header/android-6.0.0_r1/frameworks/native/include C:/__BuildSource/__LIB__/android-aosp-header/android-6.0.0_r1/hardware/libhardware/include C:/__BuildSource/__LIB__/android-aosp-header/other/Skia ./ extern extern/lz4 11 | CBP2NDK_CMDLINE := --ratio 2 --rotate 360 -f OutBmp.bmp 12 | # -lcutils -lutils -lbinder -lskia -lui -lsurfaceflinger -lsurfaceflinger_ddmconnection 13 | #LOCAL_ALLOW_UNDEFINED_SYMBOLS := true 14 | LOCAL_MODULE_TAGS := eng 15 | LIBCXX_FORCE_REBUILD := false 16 | LOCAL_CPP_FEATURES := rtti 17 | LOCAL_MODULE_PATH := $(TARGET_OUT)/dist 18 | include $(BUILD_EXECUTABLE) 19 | -------------------------------------------------------------------------------- /ascreencap.h: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | /// Debug only: 9 | /// #include 10 | 11 | #if defined(_DEBUG) 12 | # include 13 | typedef std::chrono::high_resolution_clock::time_point TimeWatch; 14 | # define HClockNow() std::chrono::high_resolution_clock::now() 15 | # define HClockDiff(A,B) std::chrono::duration_cast(A - B).count() 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #if defined(_DEBUG) 32 | # define __LOG_PRINT(A, ...) \ 33 | __LOG_PRINT_(A, __func__, __LINE__, __VA_ARGS__) 34 | 35 | # if defined(_ANDROID_LOG) 36 | # define __LOG_PRINT_(A, B, C, ...) \ 37 | __android_log_print(ANDROID_LOG_DEBUG, "ASCREENCAP", "+ [%s:%d] " A, B, C, __VA_ARGS__) 38 | # else 39 | # define __LOG_PRINT_(A, B, C,...) \ 40 | { fprintf(stderr, "+ [%s:%d] " A " | global: [%d][%s]\n", B, C, __VA_ARGS__, errno, strerror(errno)); errno = 0; } 41 | # endif 42 | 43 | #else 44 | # define __LOG_PRINT(A,...) 45 | #endif 46 | 47 | #define __ERROR_THIS_SET \ 48 | _err = __LINE__; 49 | 50 | #define __ERROR_BREAK_SET \ 51 | { _err = __LINE__; break; } 52 | 53 | #define __ERROR_BOOL_SET \ 54 | { _err = __LINE__; return false; } 55 | 56 | #define __NELE(a) (sizeof(a) / sizeof(a[0])) 57 | -------------------------------------------------------------------------------- /fakelib/libbinder.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "libfake.h" 3 | 4 | namespace android { 5 | 6 | class IPCThreadState; 7 | 8 | class ProcessState 9 | { 10 | public: 11 | static sp self(); 12 | void startThreadPool(); 13 | void spawnPooledThread(bool); 14 | uint32_t setThreadPoolMaxThreadCount(size_t); 15 | 16 | private: 17 | ProcessState(); 18 | ~ProcessState(); 19 | }; 20 | 21 | 22 | class IPCThreadState 23 | { 24 | public: 25 | static IPCThreadState* self(); 26 | void joinThreadPool(bool isMain = true); 27 | 28 | private: 29 | IPCThreadState(); 30 | ~IPCThreadState(); 31 | }; 32 | 33 | IPCThreadState::IPCThreadState() { 34 | LOG("IPCThreadState::IPCThreadState()\n"); 35 | } 36 | IPCThreadState::~IPCThreadState() { 37 | LOG("IPCThreadState::IPCThreadState()\n"); 38 | } 39 | IPCThreadState * IPCThreadState::self() { 40 | LOG("IPCThreadState::self()\n"); 41 | return new IPCThreadState(); 42 | } 43 | void IPCThreadState::joinThreadPool(bool b) { 44 | LOG("IPCThreadState::joinThreadPool() %d\n", b); 45 | } 46 | 47 | sp ProcessState::self() { 48 | LOG("ProcessState::self()\n"); 49 | sp p; 50 | p.m_ptr = NULL; 51 | return p; 52 | } 53 | 54 | void ProcessState::spawnPooledThread(bool b) { 55 | LOG("ProcessState::spawnPooledThread() %d\n", b); 56 | } 57 | 58 | void ProcessState::startThreadPool() { 59 | LOG("ProcessState::startThreadPool()\n"); 60 | } 61 | 62 | uint32_t ProcessState::setThreadPoolMaxThreadCount(size_t z) { 63 | LOG("ProcessState::setThreadPoolMaxThreadCount() %zu\n", z); 64 | return 0U; 65 | } 66 | 67 | ProcessState::ProcessState() { 68 | LOG("ProcessState::ProcessState()\n"); 69 | } 70 | 71 | ProcessState::~ProcessState() { 72 | LOG("ProcessState::~ProcessState()\n"); 73 | } 74 | 75 | } 76 | 77 | -------------------------------------------------------------------------------- /fakelib/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(my-dir) 2 | include $(CLEAR_VARS) 3 | LOCAL_MODULE := libgui 4 | LOCAL_INSTALLED_MODULE_STEM := libgui.so 5 | LOCAL_SDK_VERSION := 22 6 | LOCAL_CPP_EXTENSION := .cpp 7 | LOCAL_CPPFLAGS := -std=c++17 8 | LOCAL_SRC_FILES := libgui.cpp 9 | LOCAL_LDLIBS := -llog 10 | # LOCAL_SHARED_LIBRARIES := liblog 11 | LOCAL_C_INCLUDES := include 12 | LOCAL_MODULE_PATH := $(TARGET_OUT)/libs 13 | include $(BUILD_SHARED_LIBRARY) 14 | 15 | 16 | include $(CLEAR_VARS) 17 | LOCAL_MODULE := libui 18 | LOCAL_INSTALLED_MODULE_STEM := libui.so 19 | LOCAL_SDK_VERSION := 22 20 | LOCAL_CPP_EXTENSION := .cpp 21 | LOCAL_CPPFLAGS := -std=c++17 22 | LOCAL_SRC_FILES := libui.cpp 23 | LOCAL_LDLIBS := -llog 24 | # LOCAL_SHARED_LIBRARIES := liblog 25 | LOCAL_C_INCLUDES := include 26 | LOCAL_MODULE_PATH := $(TARGET_OUT)/libs 27 | include $(BUILD_SHARED_LIBRARY) 28 | 29 | 30 | include $(CLEAR_VARS) 31 | LOCAL_MODULE := libbinder 32 | LOCAL_INSTALLED_MODULE_STEM := libbinder.so 33 | LOCAL_SDK_VERSION := 22 34 | LOCAL_CPP_EXTENSION := .cpp 35 | LOCAL_CPPFLAGS := -std=c++17 36 | LOCAL_SRC_FILES := libbinder.cpp 37 | LOCAL_LDLIBS := -llog 38 | # LOCAL_SHARED_LIBRARIES := liblog 39 | LOCAL_C_INCLUDES := include 40 | LOCAL_MODULE_PATH := $(TARGET_OUT)/libs 41 | include $(BUILD_SHARED_LIBRARY) 42 | 43 | 44 | include $(CLEAR_VARS) 45 | LOCAL_MODULE := libutils 46 | LOCAL_INSTALLED_MODULE_STEM := libutils.so 47 | LOCAL_SDK_VERSION := 22 48 | LOCAL_CPP_EXTENSION := .cpp 49 | LOCAL_CPPFLAGS := -std=c++17 50 | LOCAL_SRC_FILES := libutils.cpp 51 | LOCAL_LDLIBS := -llog 52 | # LOCAL_SHARED_LIBRARIES := liblog 53 | LOCAL_C_INCLUDES := include 54 | LOCAL_MODULE_PATH := $(TARGET_OUT)/libs 55 | include $(BUILD_SHARED_LIBRARY) 56 | 57 | include $(CLEAR_VARS) 58 | LOCAL_MODULE := libart 59 | LOCAL_INSTALLED_MODULE_STEM := libart.so 60 | LOCAL_SDK_VERSION := 22 61 | LOCAL_CPP_EXTENSION := .cpp 62 | LOCAL_CPPFLAGS := -std=c++17 63 | LOCAL_SRC_FILES := libart.cpp 64 | LOCAL_LDLIBS := -llog 65 | LOCAL_LDFLAGS := -Wl,--version-script,vs-libart.txt 66 | # LOCAL_SHARED_LIBRARIES := liblog 67 | LOCAL_C_INCLUDES := include 68 | LOCAL_MODULE_PATH := $(TARGET_OUT)/libs 69 | include $(BUILD_SHARED_LIBRARY) 70 | -------------------------------------------------------------------------------- /Build-all.cmd: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | del /Q /S dist obj libs 4 | rename Application.mk Application.mk.orig 5 | 6 | echo APP_ABI := all >Application.mk 7 | echo APP_STL := c++_static >>Application.mk 8 | echo APP_BUILD_SCRIPT := Android.mk >>Application.mk 9 | echo APP_PLATFORM := android-28 >>Application.mk 10 | echo APP_BUILD_VERSION := 9 >>Application.mk 11 | @Cmd.exe /C C:\__BuildSource\__LIB__\android-ndk-r20-beta2\ndk-build.cmd NDK_APPLICATION_MK=./Application.mk NDK_PROJECT_PATH=./ APP_BUILD_VERSION=9 -j 4 12 | move libs\arm64-v8a\ascreencap dist\9\arm64-v8a\ascreencap 13 | move libs\armeabi-v7a\ascreencap dist\9\armeabi-v7a\ascreencap 14 | move libs\x86\ascreencap dist\9\x86\ascreencap 15 | move libs\x86_64\ascreencap dist\9\x86_64\ascreencap 16 | del /Q /S obj libs 17 | 18 | echo APP_ABI := all >Application.mk 19 | echo APP_STL := c++_static >>Application.mk 20 | echo APP_BUILD_SCRIPT := Android.mk >>Application.mk 21 | echo APP_PLATFORM := android-27 >>Application.mk 22 | echo APP_BUILD_VERSION := 8 >>Application.mk 23 | @Cmd.exe /C C:\__BuildSource\__LIB__\android-ndk-r20-beta2\ndk-build.cmd NDK_APPLICATION_MK=./Application.mk NDK_PROJECT_PATH=./ APP_BUILD_VERSION=8 -j 4 24 | move libs\arm64-v8a\ascreencap dist\8\arm64-v8a\ascreencap 25 | move libs\armeabi-v7a\ascreencap dist\8\armeabi-v7a\ascreencap 26 | move libs\x86\ascreencap dist\8\x86\ascreencap 27 | move libs\x86_64\ascreencap dist\8\x86_64\ascreencap 28 | del /Q /S obj libs 29 | 30 | echo APP_ABI := all >Application.mk 31 | echo APP_STL := c++_static >>Application.mk 32 | echo APP_BUILD_SCRIPT := Android.mk >>Application.mk 33 | echo APP_PLATFORM := android-21 >>Application.mk 34 | echo APP_BUILD_VERSION := 5 >>Application.mk 35 | @Cmd.exe /C C:\__BuildSource\__LIB__\android-ndk-r20-beta2\ndk-build.cmd NDK_APPLICATION_MK=./Application.mk NDK_PROJECT_PATH=./ APP_BUILD_VERSION=5 -j 4 36 | move libs\arm64-v8a\ascreencap dist\5\arm64-v8a\ascreencap 37 | move libs\armeabi-v7a\ascreencap dist\5\armeabi-v7a\ascreencap 38 | move libs\x86\ascreencap dist\5\x86\ascreencap 39 | move libs\x86_64\ascreencap dist\5\x86_64\ascreencap 40 | android-elf-cleaner.exe dist\5\armeabi-v7a\ascreencap 41 | 42 | del /Q /S obj libs 43 | move Application.mk.orig Application.mk 44 | 45 | -------------------------------------------------------------------------------- /ascreencap-ABitmapLite.h: -------------------------------------------------------------------------------- 1 | 2 | #define BMZ_MAGIC 0x315a4d42 3 | 4 | namespace ACapture 5 | { 6 | 7 | class ABitmapLite 8 | { 9 | public: 10 | typedef struct __attribute__((__packed__)) 11 | { 12 | uint32_t id; 13 | uint32_t osz; 14 | uint32_t dsz; 15 | uint32_t w; 16 | uint32_t h; 17 | } STREAMHEADER; 18 | 19 | typedef struct __attribute__((__packed__)) 20 | { 21 | size_t sz; 22 | uint32_t w, h, s, b, f, bpp; 23 | uint8_t *src; 24 | uint8_t *dst; 25 | } BITMAPINFODATA; 26 | 27 | typedef struct __attribute__((__packed__)) 28 | { 29 | uint16_t bfType; 30 | uint32_t bfSize; 31 | uint32_t bfReserved; // 1,2 32 | uint32_t bfOffBits; 33 | } BITMAPFILEHEADER; 34 | 35 | typedef struct __attribute__((__packed__)) 36 | { 37 | uint32_t biSize; 38 | long biWidth; 39 | long biHeight; 40 | uint16_t biPlanes; 41 | uint16_t biBitCount; 42 | uint32_t biCompression; 43 | uint32_t biSizeImage; 44 | long biXPelsPerMeter; 45 | long biYPelsPerMeter; 46 | uint32_t biClrUsed; 47 | uint32_t biClrImportant; 48 | } BITMAPINFOHEADER; 49 | 50 | typedef struct 51 | { 52 | ABitmapLite::BITMAPFILEHEADER fh; 53 | ABitmapLite::BITMAPINFOHEADER ih; 54 | } BMPHEADER; 55 | 56 | bool ishead, issdlcompat; 57 | uint32_t rat, rot; 58 | std::vector vsrc; 59 | std::vector vdst; 60 | std::vector vdstz; 61 | BITMAPINFODATA bmpdata{}; 62 | 63 | ABitmapLite(); 64 | ABitmapLite(uint32_t, uint32_t, uint32_t, uint32_t, const void*, size_t); 65 | ~ABitmapLite(); 66 | 67 | void Reset(); 68 | bool TestData(bool); 69 | void SetData(const void*, size_t); 70 | void SetData(uint32_t, uint32_t, uint32_t, uint32_t, const void*, size_t); 71 | uint8_t * GetData(size_t*); 72 | uint8_t * GetDataPack(size_t*, int32_t); 73 | # if defined(_DEBUG) 74 | uint32_t getBpp() const; 75 | # endif 76 | 77 | private: 78 | 79 | void rotateBmp(uint32_t); 80 | bool convertBmp(bool); 81 | bool headerBmp(); 82 | uint32_t getPadSrc() const; 83 | uint32_t getPadDst(uint32_t) const; 84 | # if !defined(_DEBUG) 85 | uint32_t getBpp() const; 86 | # endif 87 | 88 | }; 89 | 90 | } 91 | -------------------------------------------------------------------------------- /fakelib/include/JniInvocation.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #ifndef JNI_INVOCATION_H_included 17 | #define JNI_INVOCATION_H_included 18 | #include 19 | // JniInvocation adds a layer of indirection for applications using 20 | // the JNI invocation API to allow the JNI implementation to be 21 | // selected dynamically. Apps can specify a specific implementation to 22 | // be used by calling InitJniInvocation. If this is not done, the 23 | // library will chosen based on the value of Android system property 24 | // persist.sys.dalvik.vm.lib on the device, and otherwise fall back to 25 | // a hard-coded default implementation. 26 | class JniInvocation { 27 | public: 28 | JniInvocation(); 29 | ~JniInvocation(); 30 | // Initialize JNI invocation API. library should specifiy a valid 31 | // shared library for opening via dlopen providing a JNI invocation 32 | // implementation, or null to allow defaulting via 33 | // persist.sys.dalvik.vm.lib. 34 | bool Init(const char* library); 35 | // Exposes which library is actually loaded from the given name. The 36 | // buffer of size PROPERTY_VALUE_MAX will be used to load the system 37 | // property for the default library, if necessary. If no buffer is 38 | // provided, the fallback value will be used. 39 | static const char* GetLibrary(const char* library, char* buffer); 40 | private: 41 | bool FindSymbol(void** pointer, const char* symbol); 42 | static JniInvocation& GetJniInvocation(); 43 | jint JNI_GetDefaultJavaVMInitArgs(void* vmargs); 44 | jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args); 45 | jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count); 46 | static JniInvocation* jni_invocation_; 47 | void* handle_; 48 | jint (*JNI_GetDefaultJavaVMInitArgs_)(void*); 49 | jint (*JNI_CreateJavaVM_)(JavaVM**, JNIEnv**, void*); 50 | jint (*JNI_GetCreatedJavaVMs_)(JavaVM**, jsize, jsize*); 51 | friend jint JNI_GetDefaultJavaVMInitArgs(void* vm_args); 52 | friend jint JNI_CreateJavaVM(JavaVM** p_vm, JNIEnv** p_env, void* vm_args); 53 | friend jint JNI_GetCreatedJavaVMs(JavaVM** vms, jsize size, jsize* vm_count); 54 | }; 55 | #endif // JNI_INVOCATION_H_included 56 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | PLATFORM := armeabi-v7a 3 | NDKROOT := C:\__BuildSource\__LIB__\android-ndk-r20-beta2 4 | PROJECT := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) 5 | BUILDTAG := $(filter-out $@,$(MAKECMDGOALS)) 6 | BUILDOPT := 7 | 8 | include Application.mk 9 | include $(APP_BUILD_SCRIPT) 10 | 11 | ifeq ($(OS),Windows_NT) 12 | CONFCBP := $(shell dir *.cbp | findstr .cbp) 13 | else 14 | CONFCBP := $(shell find $("./") -name '*.cbp') 15 | endif 16 | 17 | ifneq ($(APP_ABI),all) 18 | PLATFORM = $(APP_ABI) 19 | endif 20 | 21 | ifneq ($(ANALIZE),) 22 | BUILDOPT += NDK_ANALIZE=1 23 | endif 24 | 25 | ifeq ($(BUILDTAG),Debug) 26 | BUILDOPT += V=1 NDK_DEBUG=1 27 | else 28 | BUILDOPT += -j 4 29 | endif 30 | 31 | all: allndk 32 | Debug: allndk adbsetup adbdebug buildscript rundebug 33 | Release: allndk adbsetup adbexec buildscript 34 | cleanDebug: clean 35 | cleanRelease: clean 36 | cleanall: clean 37 | 38 | allndk: 39 | @echo '==== Build $(BUILDTAG) -> $(APP_ABI) platform -> active device: [ $(PLATFORM) ] ====' 40 | @cbp2ndk.exe $(BUILDTAG) $(CONFCBP) 41 | @Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) $(BUILDOPT) 42 | 43 | clean: 44 | @echo '==== Clean ====' 45 | @Cmd.exe /C $(NDKROOT)\ndk-build.cmd NDK_APPLICATION_MK=$(PROJECT)Application.mk NDK_PROJECT_PATH=$(PROJECT) clean 46 | @Cmd.exe /C adb.exe shell rm -f /data/local/tmp/$(LOCAL_MODULE) 47 | 48 | adbsetup: 49 | @echo '==== ADB SETUP: [ $(PLATFORM) ] ====' 50 | ifeq ($(shell expr $(APP_BUILD_VERSION) \< 8), 1) 51 | @Cmd.exe /C android-elf-cleaner.exe $(PROJECT)libs\$(PLATFORM)\$(LOCAL_MODULE) 52 | endif 53 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\$(LOCAL_MODULE) /data/local/tmp/$(LOCAL_MODULE) 54 | @Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/$(LOCAL_MODULE) 55 | 56 | adbexec: 57 | @echo '==== ADB RUN: [ $(PLATFORM) ] ====' 58 | @Cmd.exe /C adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE) 59 | @Cmd.exe /C adb.exe pull /data/local/tmp/OutBmp.bmp C:/__BuildSource/__TEST__/Android/ 60 | 61 | adbdebug: 62 | @echo '==== GDB Debug: [ $(PLATFORM) ] ====' 63 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdb.setup /data/local/tmp/gdb.setup 64 | @Cmd.exe /C adb.exe push $(PROJECT)libs\$(PLATFORM)\gdbserver /data/local/tmp/gdbserver 65 | @Cmd.exe /C adb.exe shell /system/bin/chmod 0777 /data/local/tmp/gdbserver 66 | 67 | rundebug: 68 | @Cmd.exe /C DebugRemote.cmd 69 | 70 | buildscript: 71 | ifeq (,$(wildcard ./RunRemote.cmd)) 72 | @echo "adb.exe shell /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >RunRemote.cmd 73 | endif 74 | ifeq (,$(wildcard ./DebugRemote.cmd)) 75 | @echo "adb.exe forward tcp:59999 tcp:59999" >DebugRemote.cmd 76 | @echo "start \"$(PLATFORM) GDB server\" /MIN adb.exe shell /data/local/tmp/gdbserver :59999 /data/local/tmp/$(LOCAL_MODULE) $(CBP2NDK_CMDLINE)" >>DebugRemote.cmd 77 | @echo "exit" >>DebugRemote.cmd 78 | endif 79 | 80 | .PHONY: clean all 81 | 82 | -------------------------------------------------------------------------------- /fakelib/libui.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "libfake.h" 3 | 4 | namespace android { 5 | 6 | class Rect 7 | { 8 | public: 9 | int32_t left; 10 | int32_t top; 11 | int32_t right; 12 | int32_t bottom; 13 | Rect(); 14 | Rect(Rect const &); 15 | Rect(int32_t, int32_t); 16 | Rect(int32_t, int32_t, int32_t, int32_t); 17 | ~Rect(); 18 | }; 19 | 20 | // __attribute__ ((weak)) 21 | __attribute__ ((visibility ("hidden"))) Rect::Rect(int32_t x, int32_t y) : left(x), top(y) {} 22 | 23 | class GraphicBuffer 24 | { 25 | public: 26 | GraphicBuffer(uint32_t, uint32_t, int32_t, uint32_t, uint64_t, std::string); 27 | GraphicBuffer(uint32_t, uint32_t, int32_t, uint32_t, uint32_t, uint32_t, void*, bool); 28 | GraphicBuffer(const void*, uint8_t, uint32_t, uint32_t, int32_t, uint32_t, uint64_t, uint32_t); 29 | 30 | uint32_t unlock(); 31 | uint32_t lock(uint32_t, void**); 32 | uint32_t lock(uint32_t, const Rect&, void**); 33 | 34 | uint32_t getWidth() const; 35 | uint32_t getHeight() const; 36 | uint32_t getStride() const; 37 | uint64_t getUsage() const; 38 | int32_t getPixelFormat() const; 39 | uint32_t getLayerCount() const; 40 | Rect getBounds() const; 41 | uint64_t getId() const; 42 | int32_t initCheck() const; 43 | 44 | private: 45 | ~GraphicBuffer(); 46 | }; 47 | 48 | GraphicBuffer::~GraphicBuffer() {} 49 | GraphicBuffer::GraphicBuffer(uint32_t a1, uint32_t a2, int32_t a3, uint32_t a4, uint64_t a5, std::string a6) { LOG("GraphicBuffer::x()\n"); } 50 | GraphicBuffer::GraphicBuffer(uint32_t a1, uint32_t a2, int32_t a3, uint32_t a4, uint32_t a5, uint32_t a6, void*, bool a7) { LOG("GraphicBuffer::x()\n"); } 51 | GraphicBuffer::GraphicBuffer(const void *a1, uint8_t a2, uint32_t a3, uint32_t a4, int32_t a5, uint32_t a6, uint64_t a7, uint32_t a8) { LOG("GraphicBuffer::x()\n"); } 52 | uint32_t GraphicBuffer::unlock() { LOG("GraphicBuffer::x()\n"); return 0U; } 53 | uint32_t GraphicBuffer::lock(uint32_t a1, void **a2) { LOG("GraphicBuffer::x()\n"); return 0U; } 54 | uint32_t GraphicBuffer::lock(uint32_t a1, const Rect& a2, void **a3) { LOG("GraphicBuffer::x()\n"); return 0U; } 55 | uint32_t GraphicBuffer::getWidth() const { LOG("GraphicBuffer::x()\n"); return 0U; } 56 | uint32_t GraphicBuffer::getHeight() const { LOG("GraphicBuffer::x()\n"); return 0U; } 57 | uint32_t GraphicBuffer::getStride() const { LOG("GraphicBuffer::x()\n"); return 0U; } 58 | uint64_t GraphicBuffer::getUsage() const { LOG("GraphicBuffer::x()\n"); return 0LLU; } 59 | int32_t GraphicBuffer::getPixelFormat() const { LOG("GraphicBuffer::x()\n"); return 0; } 60 | uint32_t GraphicBuffer::getLayerCount() const { LOG("GraphicBuffer::x()\n"); return 0U; } 61 | Rect GraphicBuffer::getBounds() const { LOG("GraphicBuffer::x()\n"); return Rect(0, 0); } 62 | uint64_t GraphicBuffer::getId() const { LOG("GraphicBuffer::x()\n"); return 0LLU; } 63 | int32_t GraphicBuffer::initCheck() const { LOG("GraphicBuffer::x()\n"); return 0; } 64 | 65 | /// include /platform/frameworks/native/libs/ui/include/ui/PixelFormat.h 66 | uint32_t bytesPerPixel(int32_t format) { LOG("bytesPerPixel()\n"); return 0U; } 67 | uint32_t bitsPerPixel(int32_t format) { LOG("bitsPerPixel()\n"); return 0U; } 68 | 69 | }; 70 | 71 | -------------------------------------------------------------------------------- /ascreencap.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ascreencap.h" 3 | #include "ascreencap-AScreenConf.h" 4 | #include "ascreencap-ABitmapLite.h" 5 | #include "ascreencap-AScreenCap.h" 6 | #include "extern/argh.h" 7 | #include 8 | #include 9 | 10 | 11 | /* 12 | #include 13 | 14 | static struct sigaction sigThis{}; 15 | 16 | static void exitSignal(int sig) 17 | { 18 | __LOG_PRINT("exitHandler signal: [%d]", sig); 19 | exit(1); 20 | } 21 | 22 | static bool setSignal() 23 | { 24 | sigThis.sa_handler = exitSignal; 25 | sigThis.sa_flags = 0; 26 | ::sigemptyset(&sigThis.sa_mask); 27 | ::sigaddset(&sigThis.sa_mask, SIGPIPE); 28 | 29 | return ( 30 | (::sigaction(SIGINT, &sigThis, NULL) == 0) && 31 | (::sigprocmask(SIG_BLOCK, &sigThis.sa_mask, NULL) == 0) 32 | ); 33 | } 34 | */ 35 | 36 | int main(int argc, char **argv) 37 | { 38 | int32_t ret = 0; 39 | # if defined(_DEBUG) 40 | auto _t1 = HClockNow(); 41 | # endif 42 | 43 | # if (__ANDROID_VER__ >= 8) 44 | android::ProcessState::self()->setThreadPoolMaxThreadCount(0); 45 | android::ProcessState::self()->startThreadPool(); 46 | # elif ((__ANDROID_VER__ <= 7) && (__ANDROID_VER__ >= 5)) 47 | android::sp proc(android::ProcessState::self()); 48 | android::ProcessState::self()->startThreadPool(); 49 | # endif 50 | 51 | /* 52 | if (!setSignal()) 53 | { 54 | __LOG_PRINT("Signal not set: [%s]", strerror(errno)); 55 | return 120; 56 | } 57 | */ 58 | 59 | ACapture::AScreenConf cnf(argc, argv); 60 | 61 | if (cnf.IsInfo) 62 | { 63 | cnf.printInfo(); 64 | return 0; 65 | } 66 | else if (cnf.IsHelp) 67 | { 68 | cnf.printHelp(); 69 | return 0; 70 | } 71 | 72 | ACapture::AScreenCap sc; 73 | sc.setRatio(cnf.Ratio); 74 | sc.setRotate(cnf.Rotate); 75 | sc.setNohead(cnf.IsSDL2Compatible); 76 | 77 | # if defined(_DEBUG) 78 | auto _t2 = HClockNow(); 79 | # endif 80 | 81 | do 82 | { 83 | if (cnf.IsCapFile) 84 | { 85 | if (sc.getScreen()) 86 | { 87 | # if defined(_DEBUG) 88 | auto _t3 = HClockNow(); 89 | # endif 90 | if (!sc.getError()) 91 | if (sc.saveFile(cnf.FileName, cnf.IsCapPack, cnf.FastPack)) 92 | { 93 | # if defined(_DEBUG) 94 | auto _t4 = HClockNow(); 95 | auto _d2 = HClockDiff(_t2, _t1); 96 | auto _d3 = HClockDiff(_t3, _t2); 97 | auto _d4 = HClockDiff(_t4, _t3); 98 | auto _d0 = HClockDiff(_t4, _t1); 99 | __LOG_PRINT( 100 | "End, load (ms.) -> base: [%lld], capture: [%lld], image: [%lld], total: [%lld] | internal-err: [%d]", 101 | _d2, _d3, _d4, _d0, sc.getError() 102 | ); 103 | # endif 104 | break; 105 | } 106 | } 107 | __LOG_PRINT("Capture to file error [%d]", sc.getError()); 108 | ret = 127; break; 109 | } 110 | else if (cnf.IsCapStdOut) 111 | { 112 | if (sc.getScreen()) 113 | { 114 | if (!sc.getError()) 115 | if (sc.printStdout(cnf.IsCapPack, cnf.FastPack)) 116 | break; 117 | } 118 | __LOG_PRINT("Capture to stdout error [%d]", sc.getError()); 119 | ret = 127; break; 120 | } 121 | else if (cnf.IsCapStream) 122 | { 123 | sc.getStream(cnf.FastPack); 124 | } 125 | } 126 | while (0); 127 | 128 | /// ? fuck! long wait.. 129 | //android::IPCThreadState::self()->joinThreadPool(); 130 | return ret; 131 | } 132 | -------------------------------------------------------------------------------- /AScreencap.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 97 | 98 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android fast screen capture - image or compressed image stream output 2 | 3 | - Android fast screen capture take a screenshot or compressed stream on any other Android device. 4 | - Not needed root devices. 5 | - ADB required (default run permissions using). 6 | - For best perfomance using `OpenMP` for Android. 7 | - Include all using system library, fake version (for [Android 5.1.1](https://github.com/ClnViewer/android-platform-headers/tree/master/android-5.1.1_r1) headers) 8 | - Default build tools: [ndk-build](https://developer.android.com/ndk/downloads?hl=hi#beta-downloads), including Code::Blocks project using [C::B NDK project template](https://github.com/ClnViewer/Code-Blocks-Android-NDK), NDK build auto configuration support. 9 | 10 | ---- 11 | 12 | - [Features](#features) 13 | - [Stream/Image compressed - header format using](#streamimage-compressed---header-format-using) 14 | - [Installing pre-build binary](#installing-pre-build) 15 | - [Using from command line](#using) 16 | - [Example using SDL2 output format](#example-using-sdl2-output-format) 17 | 18 | ---- 19 | 20 | ### Features 21 | 22 | - image output format: **raw bitmap** `24 bpp`, include header. 23 | - video stream output format: **raw compressed bitmap** `lz4 stream` - `24 bpp`, include header + packet header. 24 | - video stream is 5 - 20 fps, depends on the CPU device. 25 | - pack image by ratio: valid values `1-9` (`lz4`). 26 | - resize image by ratio: valid values `1-5`. 27 | - rotate image: `90,180,270` 28 | - mirror image. 29 | - SDL2 [Texture](#example-using-sdl2-output-format) output compatible mode: Landscape screen. 30 | - save image to location specified (bmp format). 31 | - default save path: /data/local/tmp/AScreenCap.bmp 32 | 33 | Run time statistic, milliseconds: 34 | 35 | 5 ms. - load and initialization 36 | 40-151 ms. - capture screen - android::ScreenshotClient(), depends on the CPU device 37 | 40 ms. - image convert, resize and rotate 38 | 196 ms. - maximal total time 39 | 40 | 41 | ### Stream/Image compressed - header format using 42 | 43 | Packet stream include no pack header, size 160bit `uint32[5]`, after image compressed body: 44 | - octet `0` - unique identifier `BMZ1` (`0x315a4d42`/`828001602`). 45 | - octet `1` - size to uncompressed image. 46 | - octet `2` - size to compressed image. 47 | - octet `3` - image width. 48 | - octet `4` - image height. 49 | 50 | ### Installing pre-build 51 | 52 | Download binary for you device from [dist/](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/) directory: 53 | 54 | Building details: 55 | 56 | #### Android 5.x - 7.x | [armeabi-v7a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/5/armeabi-v7a) | [arm64-v8a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/5/arm64-v8a) | [x86](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/5/x86) | [x86_64](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/5/x86_64) 57 | 58 | > Application platform: `android-21` 59 | > Android system AOSP library version compatible: `5.1.1 - 7.x.x` 60 | > NDK build version: `r20-beta2` 61 | 62 | #### Android 8.x | [armeabi-v7a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/8/armeabi-v7a) | [arm64-v8a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/8/arm64-v8a) | [x86](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/8/x86) | [x86_64](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/8/x86_64) 63 | 64 | > Application platform: `android-27` 65 | > Android system AOSP library version compatible: `8.0.0 - 8.1.x` 66 | > NDK build version: `r20-beta2` 67 | 68 | #### Android 9.x | [armeabi-v7a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/9/armeabi-v7a) | [arm64-v8a](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/9/arm64-v8a) | [x86](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/9/x86) | [x86_64](https://github.com/ClnViewer/Android-fast-screen-capture/blob/master/dist/9/x86_64) 69 | 70 | > Application platform: `android-28` 71 | > Android system AOSP library version compatible: `9.0.0 - 9.1.x` 72 | > NDK build version: `r20-beta2` 73 | 74 | Using ADB to send binary to device: 75 | 76 | adb push dist//ascreencap /data/local/tmp/ 77 | adb shell chmod 0777 /data/local/tmp/ascreencap 78 | 79 | ### Using 80 | 81 | Command line options: 82 | 83 | -f --file : output save to file, value is name 84 | -s --stream : output to loop stream (STDOUT) 85 | --stdout : output to STDOUT 86 | -p --pack : output pack lz4 algorithm, valid value 1-9 87 | --sdl : output SDL2 Texture compatible mode: Landscape screen 88 | --ratio : image resize ratio, valid scale 1-5 89 | --rotate : image rotate: 90,180,270, value 360 = mirror 90 | -h --help : this help screen 91 | 92 | Example run: 93 | 94 | adb exec-out /data/local/tmp/ascreencap -f /data/local/tmp/my.bmp 95 | adb exec-out /data/local/tmp/ascreencap -f /data/local/tmp/my.bmz // << save lz4 compressed image 96 | adb exec-out /data/local/tmp/ascreencap --rotate 90 --ratio 2 97 | adb exec-out /data/local/tmp/ascreencap --rotate 360 // << mirror image :) 98 | adb exec-out /data/local/tmp/ascreencap --stream 99 | 100 | 101 | ### Example using SDL2 output format 102 | 103 | Run: 104 | 105 | ```shell 106 | adb exec-out /data/local/tmp/ascreencap --stream --sdl --ratio 2 | my-capture-prog.executable 107 | ``` 108 | 109 | Part of code `my-capture-prog.executable` 110 | 111 | ```C++ 112 | /// check data header valid 113 | uint32_t *id = 'data from ascreencap'; 114 | if (*id != 0x315a4d42) 115 | return; 116 | 117 | /// begin SDL2 Create Texture 118 | uint32_t *width = 'data from ascreencap' + (sizeof(uint32_t) * 3); 119 | uint32_t *height = 'data from ascreencap' + (sizeof(uint32_t) * 4); 120 | 121 | SDL_Texture *texture = SDL_CreateTexture( 122 | renderer, 123 | SDL_PIXELFORMAT_RGB24, 124 | SDL_TEXTUREACCESS_STREAMING, 125 | *width, 126 | *height 127 | ); 128 | 129 | /// ... 130 | 131 | /// get uncompressed size from header 132 | uint32_t *psize = 'data from ascreencap' + sizeof(uint32_t); 133 | /// offset data = first 160bit uint32[5] data header from ascreencap 134 | uint32_t offset = sizeof(uint32_t) * 5; 135 | /// uncompress data from ascreencap, using lz4 136 | uint8_t *uncompressdata = ...lz4('data from ascreencap' + offset) 137 | 138 | void *pix = nullptr; 139 | int32_t pitch = 0; 140 | 141 | SDL_LockTexture(texture, nullptr, &pix, &pitch); 142 | if ((!pix) || (!pitch)) 143 | return; 144 | 145 | ::memcpy(pix, uncompressdata, *psize); 146 | 147 | SDL_UnlockTexture(texture); 148 | 149 | ``` 150 | 151 | See full [ADB capture source](https://github.com/ClnViewer/ADB-Android-Viewer/blob/f61a59666fd888ba99c79537f0b4ae4c696eec13/src/ADBDriverDLL/src/DriverSocket/DriverSocketCapture.cpp#L7) 152 | 153 | -------------------------------------------------------------------------------- /ascreencap-AScreenConf.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ascreencap.h" 3 | #include "ascreencap-AScreenConf.h" 4 | #include "extern/argh.h" 5 | #include "version.h" 6 | 7 | #define __CONF_CAPFILE "-f", "--file" 8 | #define __CONF_CAPPACK "-p", "--pack" 9 | #define __CONF_CAPRATIO "", "--ratio" 10 | #define __CONF_CAPROTATE "", "--rotate" 11 | #define __CONF_CAPSTREAM "-s", "--stream" 12 | #define __CONF_CAPSTDOUT "", "--stdout" 13 | #define __CONF_CAPSDL "", "--sdl" 14 | #define __CONF_CAPHELP "-h", "--help" 15 | #define __CONF_CAPINFO "-i", "--info" 16 | 17 | #define __HELP_PRINT(A) fprintf(stdout, "\t\t%s\t%s\t%s\n", (A).key1, (A).key2, (A).desc) 18 | #define __HELP_SET_(A,B,C) .key1 = A, .key2 = B, .desc = C 19 | #define __HELP_SET(...) __HELP_SET_(__VA_ARGS__) 20 | 21 | namespace ACapture 22 | { 23 | 24 | struct help_s 25 | { 26 | const char *key1; 27 | const char *key2; 28 | const char *desc; 29 | }; 30 | 31 | static struct help_s helps[] = 32 | { 33 | { 34 | __HELP_SET(__CONF_CAPFILE, "\t: output save to file, value is name") 35 | }, 36 | { 37 | __HELP_SET(__CONF_CAPSTREAM, ": output to loop stream (STDOUT)") 38 | }, 39 | { 40 | __HELP_SET(__CONF_CAPSTDOUT, ": output to STDOUT") 41 | }, 42 | { 43 | __HELP_SET(__CONF_CAPPACK, "\t: output pack lz4 algorithm") 44 | }, 45 | { 46 | __HELP_SET(__CONF_CAPSDL, "\t: output SDL2 texture compatible mode: Landscape screen") 47 | }, 48 | { 49 | __HELP_SET(__CONF_CAPRATIO, "\t: image resize ratio, valid scale 1-5") 50 | }, 51 | { 52 | __HELP_SET(__CONF_CAPROTATE, ": image rotate: 90,180,270, value 360 = mirror") 53 | }, 54 | { 55 | __HELP_SET(__CONF_CAPHELP, "\t: this help screen") 56 | }, 57 | { 58 | __HELP_SET(__CONF_CAPINFO, "\t: build information") 59 | } 60 | }; 61 | 62 | static uint32_t strToUint(std::string const opt) 63 | { 64 | try 65 | { 66 | return stoul(opt); 67 | } 68 | catch (std::invalid_argument & _ex) 69 | { 70 | # if defined(_DEBUG) 71 | __LOG_PRINT("CONFIG ERROR: -> (%s)", _ex.what()); 72 | # endif 73 | return 0U; 74 | } 75 | catch (std::out_of_range & _ex) 76 | { 77 | # if defined(_DEBUG) 78 | __LOG_PRINT("CONFIG ERROR: -> (%s)", _ex.what()); 79 | # endif 80 | return 0U; 81 | } 82 | catch (...) 83 | { 84 | return 0U; 85 | } 86 | } 87 | 88 | void AScreenConf::printInfo() 89 | { 90 | fprintf(stdout, "ascreencap - v.%s, build: %s.%s.%s [Android v.%d, api %d]", 91 | ACAP_FULLVERSION_STRING, ACAP_DATE, ACAP_MONTH, ACAP_YEAR, 92 | __ANDROID_VER__, __ANDROID_API__ 93 | ); 94 | } 95 | 96 | void AScreenConf::printHelp() 97 | { 98 | fprintf(stdout, "\n\tAndroid Screen Capture - v.%s, rev:%s, build: %s.%s.%s\n", 99 | ACAP_FULLVERSION_STRING, ACAP_SVN_REVISION, ACAP_DATE, ACAP_MONTH, ACAP_YEAR 100 | ); 101 | 102 | # if ((__ANDROID_VER__ == 9) || (__ANDROID_VER__ == 8)) 103 | fprintf(stdout, "\tBuild to Android version v.%d - API %d\n",__ANDROID_VER__, __ANDROID_API__); 104 | # elif ((__ANDROID_VER__ <= 7) && (__ANDROID_VER__ >= 5)) 105 | fprintf(stdout, "\tBuild to Android version v.5, v.6, v.7 - API %d\n", __ANDROID_API__); 106 | # elif (__ANDROID_API__ >= 17) 107 | fprintf(stdout, "\tBuild to Android version >= v.4 - API %d\n", __ANDROID_API__); 108 | # else 109 | fprintf(stdout, "\tBuild to unknown Android version, broken..\n"); 110 | # endif 111 | 112 | fprintf(stdout, "\tascreencap - replaced version of default screencap utility\n"); 113 | fprintf(stdout, "\tgit: https://github.com/ClnViewer/Android-fast-screen-capture.git\n\n\n"); 114 | for (uint32_t i = 0U; i < __NELE(helps); i++) 115 | __HELP_PRINT(helps[i]); 116 | } 117 | 118 | AScreenConf::AScreenConf(int32_t argc, char **argv) 119 | : _err(0), 120 | IsCapStream(false), IsCapFile(false), IsCapStdOut(false), 121 | IsCapRatio(false), IsCapRotate(false), IsCapPack(false), 122 | IsSDL2Compatible(false), IsHelp(false), IsInfo(false), 123 | Ratio(0U), Rotate(0U), FastPack(0U) 124 | { 125 | argh::parser lcmd({ 126 | __CONF_CAPSTREAM, 127 | __CONF_CAPFILE, 128 | __CONF_CAPPACK, 129 | __CONF_CAPRATIO, 130 | __CONF_CAPROTATE, 131 | __CONF_CAPSTDOUT, 132 | __CONF_CAPSDL, 133 | __CONF_CAPHELP, 134 | __CONF_CAPINFO 135 | }); 136 | 137 | lcmd.parse(argc, argv); 138 | 139 | size_t sp; 140 | std::string sratio; 141 | std::string srotate; 142 | std::string spack; 143 | 144 | IsSDL2Compatible = (lcmd[{ __CONF_CAPSDL }]); 145 | IsHelp = (lcmd[{ __CONF_CAPHELP }]); 146 | IsInfo = (lcmd[{ __CONF_CAPINFO }]); 147 | IsCapStdOut = (lcmd[{ __CONF_CAPSTDOUT }]); 148 | IsCapStream = (lcmd[{ __CONF_CAPSTREAM }]); 149 | IsCapFile = !(!(lcmd({ __CONF_CAPFILE }) >> FileName)); 150 | IsCapRatio = !(!(lcmd({ __CONF_CAPRATIO }) >> sratio)); 151 | IsCapRotate = !(!(lcmd({ __CONF_CAPROTATE }) >> srotate)); 152 | IsCapPack = !(!(lcmd({ __CONF_CAPPACK }) >> spack)); 153 | 154 | if ((IsHelp) || (IsInfo)) 155 | return; 156 | 157 | if (!IsCapStdOut) 158 | { 159 | if ((!IsCapFile) || (!FileName.length())) 160 | FileName.assign("ACapture.bmp"); 161 | else 162 | { 163 | if ((sp = FileName.find_last_of(".")) != std::wstring::npos) 164 | { 165 | std::string ext = FileName.substr(sp, FileName.length() - sp); 166 | if (!ext.compare(0U, ext.length(), ".bmz")) 167 | IsCapPack = true; 168 | } 169 | } 170 | if (FileName.find("/") == std::wstring::npos) 171 | FileName.insert(0, "/data/local/tmp/"); 172 | 173 | IsCapFile = ((IsCapFile) ? IsCapFile : (!IsCapStream)); 174 | IsCapStream = ((IsCapFile) ? false : IsCapStream); 175 | } 176 | else 177 | IsCapStream = IsCapFile = false; 178 | 179 | if ((IsCapRatio) && (sratio.length())) 180 | { 181 | Ratio = strToUint(sratio); 182 | 183 | if (Ratio) 184 | { 185 | Ratio = ((Ratio > 5U) ? 5U : Ratio); 186 | } 187 | else 188 | IsCapRatio = false; 189 | } 190 | 191 | if ((IsCapRotate) && (srotate.length())) 192 | { 193 | switch ((Rotate = strToUint(srotate))) 194 | { 195 | case 90: 196 | case 180: 197 | case 270: 198 | case 360: /// mirror mode or SDL2 mode 199 | break; 200 | default: 201 | { 202 | IsCapRotate = false; 203 | Rotate = 0U; 204 | break; 205 | } 206 | } 207 | } 208 | 209 | if ((IsSDL2Compatible) && (!IsCapRotate)) 210 | Rotate = 360U; 211 | 212 | if ((IsCapPack) && (spack.length())) 213 | { 214 | FastPack = strToUint(spack); 215 | FastPack = ((FastPack > 9) ? 0 : (9 - FastPack)); 216 | } 217 | 218 | # if defined(_DEBUG) 219 | __LOG_PRINT("CONFIG SET: ->\n" \ 220 | "\tFile path:\t[%s]\n" \ 221 | "\tRatio:\t\t[%u]\n" \ 222 | "\tRotate:\t[%u]\n" \ 223 | "\tFastPack:\t[%u]\n" \ 224 | "\tIsNoHeader:\t[%d]\n" \ 225 | "\tIsCapStdOut:\t[%d]\n" \ 226 | "\tIsCapStream:\t[%d]\n" \ 227 | "\tIsCapFile:\t[%d]\n" \ 228 | "\tIsCapRatio:\t[%d]\n" \ 229 | "\tIsCapRotate:\t[%d]\n" \ 230 | "\tIsCapPack:\t[%d]\n", 231 | FileName.c_str(), 232 | Ratio, Rotate, FastPack, 233 | IsSDL2Compatible, IsCapStdOut, IsCapStream, IsCapFile, IsCapRatio, IsCapRotate, IsCapPack 234 | ); 235 | # endif 236 | 237 | } 238 | 239 | } 240 | -------------------------------------------------------------------------------- /ascreencap-AScreenCap.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ascreencap.h" 3 | #include "ascreencap-ABitmapLite.h" 4 | #include "ascreencap-AScreenCap.h" 5 | 6 | /// android::GraphicBuffer method 7 | #if (__ANDROID_VER__ >= 9) 8 | # define acap_release() \ 9 | if (_sc != nullptr) _sc->unlock() 10 | 11 | # define acap_size() \ 12 | static_cast(_sc->getStride() * _sc->getHeight() * android::bytesPerPixel(_sc->getPixelFormat())) 13 | 14 | # define acap_getFormat() \ 15 | _sc->getPixelFormat() 16 | 17 | # define acap_getPixels() \ 18 | vbdata 19 | 20 | # define acap_getWidth() \ 21 | _sc->getWidth() 22 | 23 | # define acap_getHeight() \ 24 | _sc->getHeight() 25 | 26 | # define acap_getStride() \ 27 | _sc->getStride() 28 | 29 | 30 | /// android::ScreenshotClient method 31 | #else 32 | 33 | # define acap_release() \ 34 | _sc.release() 35 | 36 | # define acap_size() \ 37 | static_cast(_sc.getSize()) 38 | 39 | # define acap_getFormat() \ 40 | _sc.getFormat() 41 | 42 | # define acap_getPixels() \ 43 | _sc.getPixels() 44 | 45 | # define acap_getWidth() \ 46 | _sc.getWidth() 47 | 48 | # define acap_getHeight() \ 49 | _sc.getHeight() 50 | 51 | # define acap_getStride() \ 52 | _sc.getStride() 53 | 54 | #endif 55 | 56 | 57 | namespace ACapture 58 | { 59 | 60 | AScreenCap::AScreenCap() 61 | : _adata({}), _err(0), _ready(false) 62 | { 63 | # if (__ANDROID_VER__ < 9) 64 | _sc = android::ScreenshotClient(); 65 | # endif 66 | 67 | if ((_dsp = android::SurfaceComposerClient::getBuiltInDisplay( 68 | android::ISurfaceComposer::eDisplayIdMain 69 | )) == nullptr) 70 | __ERROR_THIS_SET; 71 | } 72 | 73 | AScreenCap::~AScreenCap() 74 | { 75 | acap_release(); 76 | } 77 | 78 | int32_t AScreenCap::getError() const 79 | { 80 | return _err; 81 | } 82 | 83 | void AScreenCap::setRatio(uint32_t r) 84 | { 85 | _adata.rat = r; 86 | } 87 | 88 | void AScreenCap::setRotate(uint32_t r) 89 | { 90 | _adata.rot = r; 91 | } 92 | 93 | void AScreenCap::setNohead(bool b) 94 | { 95 | _adata.issdlcompat = b; 96 | } 97 | 98 | bool AScreenCap::saveFile(std::string const & fname, bool ispack, int32_t fast) 99 | { 100 | int32_t fd = -1; 101 | errno = 0; 102 | 103 | do 104 | { 105 | int32_t _len; 106 | size_t _psz = 0U; 107 | uint8_t *_dst = ((ispack) ? _adata.GetDataPack(&_psz, fast) : _adata.GetData(&_psz)); 108 | 109 | if ((!_psz) || (!_dst)) 110 | __ERROR_BOOL_SET; 111 | 112 | if ((fd = open(fname.c_str(), O_RDWR | O_CREAT, 0666)) < 0) 113 | break; 114 | if ((_len = write(fd, _dst, _psz)) != static_cast(_psz)) 115 | break; 116 | 117 | close(fd); 118 | # if defined(_DEBUG) 119 | __LOG_PRINT("Wrote %d/%zu bytes to %s", _len, _psz, fname.c_str()); 120 | # endif 121 | return true; 122 | } 123 | while(0); 124 | 125 | if (fd > -1) 126 | close(fd); 127 | 128 | # if defined(_DEBUG) 129 | __LOG_PRINT("-> error: %s", fname.c_str()); 130 | # endif 131 | __ERROR_BOOL_SET; 132 | } 133 | 134 | bool AScreenCap::printStdout(bool ispack, int32_t fast) 135 | { 136 | errno = 0; 137 | size_t _psz = 0U; 138 | uint8_t *_dst = ((ispack) ? _adata.GetDataPack(&_psz, fast) : _adata.GetData(&_psz)); 139 | 140 | if ((!_psz) || (!_dst)) 141 | __ERROR_BOOL_SET; 142 | 143 | __LOG_PRINT("-> print stdout: [%d/%d] %zu", ispack, fast, _psz); 144 | write(dup(STDOUT_FILENO), _dst, _psz); 145 | return true; 146 | } 147 | 148 | bool AScreenCap::getScreen() 149 | { 150 | _err = 0; 151 | errno = 0; 152 | 153 | do 154 | { 155 | _adata.Reset(); 156 | 157 | if (!sysCap()) 158 | __ERROR_BREAK_SET; 159 | 160 | errno = 0; 161 | 162 | # if (__ANDROID_VER__ >= 9) 163 | if (_sc == nullptr) 164 | __ERROR_BREAK_SET; 165 | 166 | void *vbdata = nullptr; 167 | if (_sc->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &vbdata) != android::NO_ERROR) 168 | __ERROR_BREAK_SET; 169 | 170 | if (vbdata == nullptr) 171 | __ERROR_BREAK_SET; 172 | 173 | # endif 174 | 175 | _adata.SetData( 176 | acap_getWidth(), 177 | acap_getHeight(), 178 | acap_getStride(), 179 | acap_getFormat(), 180 | acap_getPixels(), 181 | acap_size() 182 | ); 183 | 184 | if (!_adata.TestData(true)) 185 | __ERROR_BREAK_SET; 186 | 187 | # if defined(_DEBUG) 188 | __LOG_PRINT("-> getScreen -> point: %ux%u", acap_getWidth(), acap_getHeight()); 189 | __LOG_PRINT("-> getScreen -> stride: %u", acap_getStride()); 190 | __LOG_PRINT("-> getScreen -> format: %d/%u/%u", acap_getFormat(), android::bytesPerPixel(acap_getFormat()), _adata.getBpp()); 191 | __LOG_PRINT("-> getScreen -> size: %zu", acap_size()); 192 | # endif 193 | 194 | # if defined(_DEBUG_RAW_FILE) 195 | FILE *fp; 196 | static const char *fnameraw = "/data/local/tmp/OutBitmap-getScreen.raw"; 197 | __LOG_PRINT("-> getScreen -> write debug RAW file: %s", fnameraw); 198 | if ((fp = fopen(fnameraw, "w"))) 199 | { 200 | # if (__ANDROID_VER__ >= 9) 201 | int sraw = fwrite(vbdata, 1, acap_size(), fp); 202 | # else 203 | int sraw = fwrite(_sc.getPixels(), 1, _sc.getSize(), fp); 204 | # endif 205 | fclose(fp); 206 | __LOG_PRINT("-> getScreen -> wrote to file: %d bytes.", sraw); 207 | } 208 | # endif 209 | 210 | } 211 | while (0); 212 | 213 | if (_err) 214 | _adata.Reset(); 215 | 216 | acap_release(); 217 | 218 | return (!_err); 219 | } 220 | 221 | void AScreenCap::getStream(int32_t fast) 222 | { 223 | int32_t fd = dup(STDOUT_FILENO); 224 | _ready = false; 225 | std::thread thr 226 | { 227 | [=]() 228 | { 229 | while(true) 230 | { 231 | while(_ready.load()) 232 | std::this_thread::yield(); 233 | 234 | if (sysCap()) 235 | _ready = true; 236 | } 237 | } 238 | }; 239 | do 240 | { 241 | if ((!getLoop()) || (getError())) 242 | continue; 243 | 244 | size_t _psz = 0U; 245 | uint8_t *_dst = _adata.GetDataPack(&_psz, fast); 246 | 247 | if ((_dst) && (_psz)) 248 | write(fd, _dst, _psz); 249 | } 250 | while (true); 251 | 252 | try 253 | { 254 | if (thr.joinable()) 255 | thr.join(); 256 | } 257 | catch (...) {} 258 | } 259 | 260 | bool AScreenCap::sysCap() 261 | { 262 | acap_release(); 263 | 264 | # if (__ANDROID_VER__ >= 9) 265 | if (android::ScreenshotClient::capture( 266 | _dsp, android::Rect(), 0, 0, INT32_MIN, INT32_MAX, false, 0U, &_sc 267 | ) != android::NO_ERROR) 268 | # elif (__ANDROID_VER__ == 8) 269 | if (_sc.update(_dsp, android::Rect(0, 0), 0, 0, INT32_MIN, INT32_MAX, false, 0) != android::NO_ERROR) 270 | # elif (__ANDROID_VER__ == 7) 271 | if (_sc.update(_dsp, android::Rect(0, 0), 0U, 0U, 0U, -1U, false, 0) != android::NO_ERROR) 272 | # elif ((__ANDROID_VER__ == 6) || (__ANDROID_VER__ == 5)) 273 | if (_sc.update(_dsp, android::Rect(0, 0), false) != android::NO_ERROR) 274 | # elif (__ANDROID_API__ >= 17) 275 | if (_sc.update(_dsp) != android::NO_ERROR) 276 | # else 277 | if (_sc.update() != android::NO_ERROR) 278 | # endif 279 | return false; 280 | return true; 281 | } 282 | 283 | bool AScreenCap::getLoop() 284 | { 285 | _err = 0; 286 | errno = 0; 287 | 288 | do 289 | { 290 | _adata.Reset(); 291 | 292 | while(!_ready.load()) 293 | std::this_thread::yield(); 294 | 295 | # if (__ANDROID_VER__ >= 9) 296 | if (_sc == nullptr) 297 | { 298 | _ready = false; 299 | break; 300 | } 301 | 302 | void *vbdata = nullptr; 303 | if (_sc->lock(android::GraphicBuffer::USAGE_SW_READ_OFTEN, &vbdata) != android::NO_ERROR) 304 | __ERROR_BREAK_SET; 305 | 306 | if (vbdata == nullptr) 307 | __ERROR_BREAK_SET; 308 | 309 | # endif 310 | 311 | _adata.SetData( 312 | acap_getWidth(), 313 | acap_getHeight(), 314 | acap_getStride(), 315 | acap_getFormat(), 316 | acap_getPixels(), 317 | acap_size() 318 | ); 319 | 320 | _ready = false; 321 | 322 | if (!_adata.TestData(true)) 323 | __ERROR_BREAK_SET; 324 | } 325 | while (0); 326 | 327 | if (_err) 328 | _adata.Reset(); 329 | 330 | return (!_err); 331 | } 332 | 333 | } 334 | -------------------------------------------------------------------------------- /fakelib/include/SurfaceComposerClient_a5_9.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2007 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | #ifndef ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H 18 | #define ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H 19 | 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | namespace android { 38 | 39 | // --------------------------------------------------------------------------- 40 | 41 | class DisplayInfo; 42 | class Composer; 43 | class ISurfaceComposerClient; 44 | class IGraphicBufferProducer; 45 | class Region; 46 | 47 | // --------------------------------------------------------------------------- 48 | 49 | class SurfaceComposerClient : public RefBase 50 | { 51 | friend class Composer; 52 | public: 53 | SurfaceComposerClient(); 54 | virtual ~SurfaceComposerClient(); 55 | 56 | // Always make sure we could initialize 57 | status_t initCheck() const; 58 | 59 | // Return the connection of this client 60 | sp connection() const; 61 | 62 | // Forcibly remove connection before all references have gone away. 63 | void dispose(); 64 | 65 | // callback when the composer is dies 66 | status_t linkToComposerDeath(const sp& recipient, 67 | void* cookie = NULL, uint32_t flags = 0); 68 | 69 | // Get a list of supported configurations for a given display 70 | static status_t getDisplayConfigs(const sp& display, 71 | Vector* configs); 72 | 73 | // Get the DisplayInfo for the currently-active configuration 74 | static status_t getDisplayInfo(const sp& display, 75 | DisplayInfo* info); 76 | 77 | // Get the index of the current active configuration (relative to the list 78 | // returned by getDisplayInfo) 79 | static int getActiveConfig(const sp& display); 80 | 81 | // Set a new active configuration using an index relative to the list 82 | // returned by getDisplayInfo 83 | static status_t setActiveConfig(const sp& display, int id); 84 | 85 | /* Triggers screen on/off or low power mode and waits for it to complete */ 86 | static void setDisplayPowerMode(const sp& display, int mode); 87 | 88 | // ------------------------------------------------------------------------ 89 | // surface creation / destruction 90 | 91 | //! Create a surface 92 | sp createSurface( 93 | const String8& name,// name of the surface 94 | uint32_t w, // width in pixel 95 | uint32_t h, // height in pixel 96 | PixelFormat format, // pixel-format desired 97 | uint32_t flags = 0 // usage flags 98 | ); 99 | 100 | //! Create a virtual display 101 | static sp createDisplay(const String8& displayName, bool secure); 102 | 103 | //! Destroy a virtual display 104 | static void destroyDisplay(const sp& display); 105 | 106 | //! Get the token for the existing default displays. 107 | //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. 108 | static sp getBuiltInDisplay(int32_t id); 109 | 110 | // ------------------------------------------------------------------------ 111 | // Composer parameters 112 | // All composer parameters must be changed within a transaction 113 | // several surfaces can be updated in one transaction, all changes are 114 | // committed at once when the transaction is closed. 115 | // closeGlobalTransaction() requires an IPC with the server. 116 | 117 | //! Open a composer transaction on all active SurfaceComposerClients. 118 | static void openGlobalTransaction(); 119 | 120 | //! Close a composer transaction on all active SurfaceComposerClients. 121 | static void closeGlobalTransaction(bool synchronous = false); 122 | 123 | //! Flag the currently open transaction as an animation transaction. 124 | static void setAnimationTransaction(); 125 | 126 | status_t hide(const sp& id); 127 | status_t show(const sp& id); 128 | status_t setFlags(const sp& id, uint32_t flags, uint32_t mask); 129 | status_t setTransparentRegionHint(const sp& id, const Region& transparent); 130 | status_t setLayer(const sp& id, uint32_t layer); 131 | status_t setAlpha(const sp& id, float alpha=1.0f); 132 | status_t setMatrix(const sp& id, float dsdx, float dtdx, float dsdy, float dtdy); 133 | status_t setPosition(const sp& id, float x, float y); 134 | status_t setSize(const sp& id, uint32_t w, uint32_t h); 135 | status_t setCrop(const sp& id, const Rect& crop); 136 | status_t setLayerStack(const sp& id, uint32_t layerStack); 137 | status_t destroySurface(const sp& id); 138 | 139 | status_t clearLayerFrameStats(const sp& token) const; 140 | status_t getLayerFrameStats(const sp& token, FrameStats* outStats) const; 141 | 142 | static status_t clearAnimationFrameStats(); 143 | static status_t getAnimationFrameStats(FrameStats* outStats); 144 | 145 | static void setDisplaySurface(const sp& token, 146 | const sp& bufferProducer); 147 | static void setDisplayLayerStack(const sp& token, 148 | uint32_t layerStack); 149 | static void setDisplaySize(const sp& token, uint32_t width, uint32_t height); 150 | 151 | /* setDisplayProjection() defines the projection of layer stacks 152 | * to a given display. 153 | * 154 | * - orientation defines the display's orientation. 155 | * - layerStackRect defines which area of the window manager coordinate 156 | * space will be used. 157 | * - displayRect defines where on the display will layerStackRect be 158 | * mapped to. displayRect is specified post-orientation, that is 159 | * it uses the orientation seen by the end-user. 160 | */ 161 | static void setDisplayProjection(const sp& token, 162 | uint32_t orientation, 163 | const Rect& layerStackRect, 164 | const Rect& displayRect); 165 | 166 | private: 167 | virtual void onFirstRef(); 168 | Composer& getComposer(); 169 | 170 | mutable Mutex mLock; 171 | status_t mStatus; 172 | sp mClient; 173 | Composer& mComposer; 174 | }; 175 | 176 | // --------------------------------------------------------------------------- 177 | 178 | class ScreenshotClient 179 | { 180 | public: 181 | // if cropping isn't required, callers may pass in a default Rect, e.g.: 182 | // capture(display, producer, Rect(), reqWidth, ...); 183 | /// Android 6.0 184 | static status_t capture( 185 | const sp& display, 186 | const sp& producer, 187 | Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 188 | uint32_t minLayerZ, uint32_t maxLayerZ, 189 | bool useIdentityTransform); 190 | 191 | /// Android 9.0 (my) 192 | static int32_t capture(const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool, uint32_t, sp*); 193 | /// and (captureSecureLayers) 194 | static int32_t capture(const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, 195 | bool, uint32_t, bool, sp*, bool&); 196 | 197 | private: 198 | mutable sp mCpuConsumer; 199 | mutable sp mProducer; 200 | CpuConsumer::LockedBuffer mBuffer; 201 | bool mHaveBuffer; 202 | 203 | public: 204 | ScreenshotClient(); 205 | ~ScreenshotClient(); 206 | 207 | // frees the previous screenshot and captures a new one 208 | // if cropping isn't required, callers may pass in a default Rect, e.g.: 209 | // update(display, Rect(), useIdentityTransform); 210 | status_t update(const sp& display, 211 | Rect sourceCrop, bool useIdentityTransform); 212 | status_t update(const sp& display, 213 | Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 214 | bool useIdentityTransform); 215 | status_t update(const sp& display, 216 | Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 217 | int32_t minLayerZ, int32_t maxLayerZ, 218 | bool useIdentityTransform); 219 | status_t update(const sp& display, 220 | Rect sourceCrop, uint32_t reqWidth, uint32_t reqHeight, 221 | int32_t minLayerZ, int32_t maxLayerZ, 222 | bool useIdentityTransform, uint32_t rotation); 223 | 224 | sp getCpuConsumer() const; 225 | 226 | // release memory occupied by the screenshot 227 | void release(); 228 | 229 | // pixels are valid until this object is freed or 230 | // release() or update() is called 231 | void const* getPixels() const; 232 | 233 | uint32_t getWidth() const; 234 | uint32_t getHeight() const; 235 | PixelFormat getFormat() const; 236 | uint32_t getStride() const; 237 | // size of allocated memory in bytes 238 | size_t getSize() const; 239 | /// (my add) > Android 6.0 240 | int32_t getDataSpace(); 241 | }; 242 | 243 | // --------------------------------------------------------------------------- 244 | }; // namespace android 245 | 246 | #endif // ANDROID_GUI_SURFACE_COMPOSER_CLIENT_H 247 | -------------------------------------------------------------------------------- /fakelib/libgui.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "libfake.h" 3 | 4 | /// typedef void native_handle_t; 5 | /// typedef uint8_t HandleWrapMethod; 6 | 7 | namespace android { 8 | 9 | class IBinder; 10 | class IGraphicBufferProducer; 11 | class DisplayInfo; 12 | 13 | /// TODO: add 14 | //class String8; 15 | //class Vector; 16 | 17 | /// declaration -> libinder ? 18 | class Rect 19 | { 20 | public: 21 | int32_t left; 22 | int32_t top; 23 | int32_t right; 24 | int32_t bottom; 25 | Rect(); 26 | Rect(Rect const &); 27 | Rect(int32_t, int32_t); 28 | Rect(int32_t, int32_t, int32_t, int32_t); 29 | ~Rect(); 30 | }; 31 | 32 | /// declaration -> libui 33 | class GraphicBuffer 34 | { 35 | public: 36 | GraphicBuffer(uint32_t, uint32_t, int32_t, uint32_t, uint64_t, std::string); 37 | GraphicBuffer(uint32_t, uint32_t, int32_t, uint32_t, uint32_t, uint32_t, void*, bool); 38 | GraphicBuffer(const void*, uint8_t, uint32_t, uint32_t, int32_t, uint32_t, uint64_t, uint32_t); 39 | 40 | uint32_t unlock(); 41 | uint32_t lock(uint32_t, void**); 42 | uint32_t lock(uint32_t, const Rect&, void**); 43 | 44 | uint32_t getWidth() const; 45 | uint32_t getHeight() const; 46 | uint32_t getStride() const; 47 | uint64_t getUsage() const; 48 | int32_t getPixelFormat() const; 49 | uint32_t getLayerCount() const; 50 | Rect getBounds() const; 51 | uint64_t getId() const; 52 | 53 | private: 54 | ~GraphicBuffer(); 55 | }; 56 | 57 | 58 | /// realisation 59 | class SurfaceComposerClient 60 | { 61 | public: 62 | 63 | SurfaceComposerClient() {} 64 | virtual ~SurfaceComposerClient() {} 65 | 66 | /* 67 | /// TODO: add 68 | static sp createDisplay(const String8& displayName, bool secure); 69 | static int32_t getDisplayConfigs(const sp& display, Vector* v) { return 0; } 70 | static int32_t getAnimationFrameStats(FrameStats* outStats) { return 0; } 71 | int32_t setTransparentRegionHint(const sp& id, const Region& transparent) { return 0; } 72 | */ 73 | static sp getBuiltInDisplay(int32_t); 74 | static void destroyDisplay(const sp&); 75 | static int32_t getDisplayInfo(const sp&, DisplayInfo*); 76 | static int getActiveConfig(const sp&); 77 | static int32_t setActiveConfig(const sp&, int); 78 | static void setDisplayPowerMode(const sp&, int); 79 | static void openGlobalTransaction(); 80 | static void closeGlobalTransaction(bool); 81 | static void setAnimationTransaction(); 82 | static int32_t clearAnimationFrameStats(); 83 | 84 | static void setDisplaySurface(const sp&, const sp&); 85 | static void setDisplayLayerStack(const sp&, uint32_t); 86 | static void setDisplaySize(const sp&, uint32_t, uint32_t); 87 | static void setDisplayProjection(const sp&, uint32_t, const Rect&, const Rect&); 88 | 89 | int32_t hide(const sp&); 90 | int32_t show(const sp&); 91 | int32_t setFlags(const sp&, uint32_t, uint32_t); 92 | int32_t setLayer(const sp&, uint32_t); 93 | int32_t setAlpha(const sp&, float); 94 | int32_t setMatrix(const sp&, float, float, float, float); 95 | int32_t setPosition(const sp&, float, float); 96 | int32_t setSize(const sp&, uint32_t, uint32_t); 97 | int32_t setCrop(const sp&, const Rect&); 98 | int32_t setLayerStack(const sp&, uint32_t); 99 | int32_t destroySurface(const sp&); 100 | int32_t clearLayerFrameStats(const sp&) const; 101 | int32_t getLayerFrameStats(const sp&, void*) const; 102 | 103 | }; 104 | 105 | sp SurfaceComposerClient::getBuiltInDisplay(int id) { 106 | LOG("SurfaceComposerClient::getBuiltInDisplay(%d)\n", id); 107 | sp p; 108 | p.m_ptr = NULL; 109 | return p; 110 | } 111 | void SurfaceComposerClient::destroyDisplay(const sp& b) { 112 | LOG("SurfaceComposerClient::destroyDisplay()\n"); 113 | } 114 | int32_t SurfaceComposerClient::getDisplayInfo(const sp& display, DisplayInfo* info) { 115 | LOG("SurfaceComposerClient::getDisplayInfo()\n"); 116 | return 0; 117 | } 118 | int32_t SurfaceComposerClient::getActiveConfig(const sp& display) { 119 | LOG("SurfaceComposerClient::getActiveConfig()\n"); 120 | return 0; 121 | } 122 | int32_t SurfaceComposerClient::setActiveConfig(const sp& display, int id) { 123 | LOG("SurfaceComposerClient::setActiveConfig()\n"); 124 | return 0; 125 | } 126 | void SurfaceComposerClient::setDisplayPowerMode(const sp& display, int mode) { 127 | LOG("SurfaceComposerClient::setDisplayPowerMode()\n"); 128 | } 129 | void SurfaceComposerClient::openGlobalTransaction() { 130 | LOG("SurfaceComposerClient::openGlobalTransaction()\n"); 131 | } 132 | void SurfaceComposerClient::closeGlobalTransaction(bool synchronous) { 133 | LOG("SurfaceComposerClient::closeGlobalTransaction()\n"); 134 | } 135 | void SurfaceComposerClient::setAnimationTransaction() { 136 | LOG("SurfaceComposerClient::setAnimationTransaction()\n"); 137 | } 138 | int32_t SurfaceComposerClient::clearAnimationFrameStats() { 139 | LOG("SurfaceComposerClient::clearAnimationFrameStats()\n"); 140 | return 0; 141 | } 142 | void SurfaceComposerClient::setDisplaySurface(const sp& token, const sp& bufferProducer) { 143 | LOG("SurfaceComposerClient::setDisplaySurface()\n"); 144 | } 145 | void SurfaceComposerClient::setDisplayLayerStack(const sp& token, uint32_t layerStack) { 146 | LOG("SurfaceComposerClient::setDisplayLayerStack()\n"); 147 | } 148 | void SurfaceComposerClient::setDisplaySize(const sp& token, uint32_t width, uint32_t height) { 149 | LOG("SurfaceComposerClient::setDisplaySize()\n"); 150 | } 151 | void SurfaceComposerClient::setDisplayProjection(const sp& token, uint32_t orientation, const Rect& layerStackRect, const Rect& displayRect) { 152 | LOG("SurfaceComposerClient::setDisplayProjection()\n"); 153 | } 154 | int32_t SurfaceComposerClient::hide(const sp& id) { return 0; } 155 | int32_t SurfaceComposerClient::show(const sp& id) { return 0; } 156 | int32_t SurfaceComposerClient::setFlags(const sp& id, uint32_t flags, uint32_t mask) { return 0; } 157 | int32_t SurfaceComposerClient::setLayer(const sp& id, uint32_t layer) { return 0; } 158 | int32_t SurfaceComposerClient::setAlpha(const sp& id, float alpha) { return 0; } 159 | int32_t SurfaceComposerClient::setMatrix(const sp& id, float dsdx, float dtdx, float dsdy, float dtdy) { return 0; } 160 | int32_t SurfaceComposerClient::setPosition(const sp& id, float x, float y) { return 0; } 161 | int32_t SurfaceComposerClient::setSize(const sp& id, uint32_t w, uint32_t h) { return 0; } 162 | int32_t SurfaceComposerClient::setCrop(const sp& id, const Rect& crop) { return 0; } 163 | int32_t SurfaceComposerClient::setLayerStack(const sp& id, uint32_t layerStack) { return 0; } 164 | int32_t SurfaceComposerClient::destroySurface(const sp& id) { return 0; } 165 | int32_t SurfaceComposerClient::clearLayerFrameStats(const sp& token) const { return 0; } 166 | int32_t SurfaceComposerClient::getLayerFrameStats(const sp& token, void* outStats) const { return 0; } 167 | 168 | 169 | /// realisation 170 | class ScreenshotClient 171 | { 172 | /* 173 | sp mHeap; 174 | uint32_t mWidth; 175 | uint32_t mHeight; 176 | PixelFormat mFormat; 177 | char data[64]; 178 | */ 179 | public: 180 | ScreenshotClient(); 181 | ~ScreenshotClient(); 182 | 183 | /// < 4.0 184 | int32_t update (); 185 | /// 4.0 - 8.0 work * 186 | int32_t update (const sp&, Rect, bool); 187 | /// 5.0 - 8.0 188 | int32_t update (const sp&, Rect, uint32_t, uint32_t, bool); 189 | /// 6.0 - 7.0 (android-6.0.1_r81 / android-7.1.2_r36) 190 | int32_t update (const sp&, Rect, uint32_t, uint32_t, uint32_t, uint32_t, bool); 191 | int32_t update (const sp&, Rect, uint32_t, uint32_t, uint32_t, uint32_t, bool, uint32_t); 192 | /// 8.0 193 | int32_t update (const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool); 194 | int32_t update (const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool, uint32_t); 195 | static int32_t capture(const sp&, const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool); 196 | /// 9.0 197 | static int32_t capture(const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool, uint32_t, sp*); 198 | static int32_t capture(const sp&, Rect, uint32_t, uint32_t, int32_t, int32_t, bool, uint32_t, bool, sp*, bool&); 199 | 200 | /* Call param: 6.0 201 | update (const sp&, Rect, 0, 0, 0, -1U, false, 0|1|2|3); 202 | */ 203 | /* Call param: 8.0 204 | update (const sp&, Rect, 0, 0, INT32_MIN, INT32_MAX, false, 0|1|2|3); 205 | */ 206 | /* Call param: 9.0 207 | capture(const sp&, Rect, 0, 0, INT32_MIN, INT32_MAX, false, uint32_t, sp*); 208 | void* base = NULL; 209 | result = outBuffer->lock(GraphicBuffer::USAGE_SW_READ_OFTEN, &base); 210 | w = outBuffer->getWidth(); 211 | h = outBuffer->getHeight(); 212 | s = outBuffer->getStride(); 213 | f = outBuffer->getPixelFormat(); 214 | d = HAL_DATASPACE_UNKNOWN; 215 | size = s * h * bytesPerPixel(f); 216 | */ 217 | 218 | 219 | void const* getPixels() const; 220 | uint32_t getWidth() const; 221 | uint32_t getHeight() const; 222 | uint32_t getStride() const; 223 | int32_t getFormat() const; 224 | size_t getSize() const; 225 | void release(); 226 | /// 6.0 - 8.0 227 | int32_t getDataSpace(); 228 | }; 229 | 230 | /// < 4.0 231 | int32_t ScreenshotClient::update () { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 232 | /// 4.0 - 8.0 work * 233 | int32_t ScreenshotClient::update (const sp& d, Rect r, bool b) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 234 | /// 5.0 - 8.0 235 | int32_t ScreenshotClient::update (const sp& d, Rect r, uint32_t w, uint32_t h, bool b) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 236 | /// 6.0 - 7.0 (android-6.0.1_r81 / android-7.1.2_r36) 237 | int32_t ScreenshotClient::update (const sp& d, Rect r, uint32_t w, uint32_t h, uint32_t x, uint32_t y, bool b) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 238 | int32_t ScreenshotClient::update (const sp& d, Rect r, uint32_t w, uint32_t h, uint32_t x, uint32_t y, bool b, uint32_t o) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 239 | /// 8.0 240 | int32_t ScreenshotClient::update (const sp& d, Rect r, uint32_t w, uint32_t h, int32_t x, int32_t y, bool b) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 241 | int32_t ScreenshotClient::update (const sp& d, Rect r, uint32_t w, uint32_t h, int32_t x, int32_t y, bool b, uint32_t o) { LOG("ScreenshotClient::update(%d)\n", __LINE__); return 1; } 242 | int32_t ScreenshotClient::capture(const sp& d, const sp& p, Rect r, uint32_t w, uint32_t h, int32_t x, int32_t y, bool b) { LOG("ScreenshotClient::capture(%d)\n", __LINE__); return 1; } 243 | /// 9.0 244 | int32_t ScreenshotClient::capture(const sp& d, Rect r, uint32_t w, uint32_t h, int32_t x, int32_t y, bool b, uint32_t o, sp *p) { LOG("ScreenshotClient::capture(%d)\n", __LINE__); return 1; } 245 | int32_t ScreenshotClient::capture(const sp& d, Rect r, uint32_t w, uint32_t h, int32_t x, int32_t y, bool b, uint32_t o, bool bb, sp *p, bool& bbb) { LOG("ScreenshotClient::capture(%d)\n", __LINE__); return 1; } 246 | 247 | ScreenshotClient::ScreenshotClient() { 248 | LOG("ScreenshotClient::ScreenshotClient()\n"); 249 | } 250 | ScreenshotClient::~ScreenshotClient() { 251 | LOG("ScreenshotClient::~ScreenshotClient()\n"); 252 | } 253 | void const* ScreenshotClient::getPixels() const { 254 | LOG("ScreenshotClient::getPixels()\n"); 255 | return NULL; 256 | } 257 | uint32_t ScreenshotClient::getWidth() const { 258 | LOG("ScreenshotClient::getWidth()\n"); 259 | return 0; 260 | } 261 | uint32_t ScreenshotClient::getHeight() const { 262 | LOG("ScreenshotClient::getHeight()\n"); 263 | return 0; 264 | } 265 | uint32_t ScreenshotClient::getStride() const { 266 | LOG("ScreenshotClient::getHeight()\n"); 267 | return 0; 268 | } 269 | int32_t ScreenshotClient::getFormat() const { 270 | LOG("ScreenshotClient::getFormat()\n"); 271 | return 0; 272 | } 273 | size_t ScreenshotClient::getSize() const { 274 | LOG("ScreenshotClient::getSize()\n"); 275 | return 0; 276 | } 277 | int32_t ScreenshotClient::getDataSpace() { /// >= 6.0 278 | LOG("ScreenshotClient::getSize()\n"); 279 | return 0; 280 | } 281 | void ScreenshotClient::release() { 282 | LOG("ScreenshotClient::release()\n"); 283 | } 284 | 285 | 286 | }; 287 | 288 | -------------------------------------------------------------------------------- /extern/argh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace argh 12 | { 13 | // Terminology: 14 | // A command line is composed of 2 types of args: 15 | // 1. Positional args, i.e. free standing values 16 | // 2. Options: args beginning with '-'. We identify two kinds: 17 | // 2.1: Flags: boolean options => (exist ? true : false) 18 | // 2.2: Parameters: a name followed by a non-option value 19 | 20 | #if !defined(__GNUC__) || (__GNUC__ >= 5) 21 | using string_stream = std::istringstream; 22 | #else 23 | // Until GCC 5, istringstream did not have a move constructor. 24 | // stringstream_proxy is used instead, as a workaround. 25 | class stringstream_proxy 26 | { 27 | public: 28 | stringstream_proxy() = default; 29 | 30 | // Construct with a value. 31 | stringstream_proxy(std::string const& value) : 32 | stream_(value) 33 | {} 34 | 35 | // Copy constructor. 36 | stringstream_proxy(const stringstream_proxy& other) : 37 | stream_(other.stream_.str()) 38 | { 39 | stream_.setstate(other.stream_.rdstate()); 40 | } 41 | 42 | void setstate(std::ios_base::iostate state) { stream_.setstate(state); } 43 | 44 | // Stream out the value of the parameter. 45 | // If the conversion was not possible, the stream will enter the fail state, 46 | // and operator bool will return false. 47 | template 48 | stringstream_proxy& operator >> (T& thing) 49 | { 50 | stream_ >> thing; 51 | return *this; 52 | } 53 | 54 | 55 | // Get the string value. 56 | std::string str() const { return stream_.str(); } 57 | 58 | std::stringbuf* rdbuf() const { return stream_.rdbuf(); } 59 | 60 | // Check the state of the stream. 61 | // False when the most recent stream operation failed 62 | operator bool() const { return !!stream_; } 63 | 64 | ~stringstream_proxy() = default; 65 | private: 66 | std::istringstream stream_; 67 | }; 68 | using string_stream = stringstream_proxy; 69 | #endif 70 | 71 | class parser 72 | { 73 | public: 74 | enum Mode { PREFER_FLAG_FOR_UNREG_OPTION = 1 << 0, 75 | PREFER_PARAM_FOR_UNREG_OPTION = 1 << 1, 76 | NO_SPLIT_ON_EQUALSIGN = 1 << 2, 77 | SINGLE_DASH_IS_MULTIFLAG = 1 << 3, 78 | }; 79 | 80 | parser() = default; 81 | 82 | parser(std::initializer_list pre_reg_names) 83 | { add_params(pre_reg_names); } 84 | 85 | parser(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) 86 | { parse(argv, mode); } 87 | 88 | parser(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION) 89 | { parse(argc, argv, mode); } 90 | 91 | void add_param(std::string const& name); 92 | void add_params(std::initializer_list init_list); 93 | 94 | void parse(const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); 95 | void parse(int argc, const char* const argv[], int mode = PREFER_FLAG_FOR_UNREG_OPTION); 96 | 97 | std::multiset const& flags() const { return flags_; } 98 | std::map const& params() const { return params_; } 99 | std::vector const& pos_args() const { return pos_args_; } 100 | 101 | // begin() and end() for using range-for over positional args. 102 | std::vector::const_iterator begin() const { return pos_args_.cbegin(); } 103 | std::vector::const_iterator end() const { return pos_args_.cend(); } 104 | size_t size() const { return pos_args_.size(); } 105 | 106 | ////////////////////////////////////////////////////////////////////////// 107 | // Accessors 108 | 109 | // flag (boolean) accessors: return true if the flag appeared, otherwise false. 110 | bool operator[](std::string const& name) const; 111 | 112 | // multiple flag (boolean) accessors: return true if at least one of the flag appeared, otherwise false. 113 | bool operator[](std::initializer_list init_list) const; 114 | 115 | // returns positional arg string by order. Like argv[] but without the options 116 | std::string const& operator[](size_t ind) const; 117 | 118 | // returns a std::istream that can be used to convert a positional arg to a typed value. 119 | string_stream operator()(size_t ind) const; 120 | 121 | // same as above, but with a default value in case the arg is missing (index out of range). 122 | template 123 | string_stream operator()(size_t ind, T&& def_val) const; 124 | 125 | // parameter accessors, give a name get an std::istream that can be used to convert to a typed value. 126 | // call .str() on result to get as string 127 | string_stream operator()(std::string const& name) const; 128 | 129 | // accessor for a parameter with multiple names, give a list of names, get an std::istream that can be used to convert to a typed value. 130 | // call .str() on result to get as string 131 | // returns the first value in the list to be found. 132 | string_stream operator()(std::initializer_list init_list) const; 133 | 134 | // same as above, but with a default value in case the param was missing. 135 | // Non-string def_val types must have an operator<<() (output stream operator) 136 | // If T only has an input stream operator, pass the string version of the type as in "3" instead of 3. 137 | template 138 | string_stream operator()(std::string const& name, T&& def_val) const; 139 | 140 | // same as above but for a list of names. returns the first value to be found. 141 | template 142 | string_stream operator()(std::initializer_list init_list, T&& def_val) const; 143 | 144 | private: 145 | string_stream bad_stream() const; 146 | std::string trim_leading_dashes(std::string const& name) const; 147 | bool is_number(std::string const& arg) const; 148 | bool is_option(std::string const& arg) const; 149 | bool got_flag(std::string const& name) const; 150 | bool is_param(std::string const& name) const; 151 | 152 | private: 153 | std::vector args_; 154 | std::map params_; 155 | std::vector pos_args_; 156 | std::multiset flags_; 157 | std::set registeredParams_; 158 | std::string empty_; 159 | }; 160 | 161 | 162 | ////////////////////////////////////////////////////////////////////////// 163 | 164 | inline void parser::parse(const char * const argv[], int mode) 165 | { 166 | int argc = 0; 167 | for (auto argvp = argv; *argvp; ++argc, ++argvp); 168 | parse(argc, argv, mode); 169 | } 170 | 171 | ////////////////////////////////////////////////////////////////////////// 172 | 173 | inline void parser::parse(int argc, const char* const argv[], int mode /*= PREFER_FLAG_FOR_UNREG_OPTION*/) 174 | { 175 | // convert to strings 176 | args_.resize(argc); 177 | std::transform(argv, argv + argc, args_.begin(), [](const char* const arg) { return arg; }); 178 | 179 | // parse line 180 | for (auto i = 0u; i < args_.size(); ++i) 181 | { 182 | if (!is_option(args_[i])) 183 | { 184 | pos_args_.emplace_back(args_[i]); 185 | continue; 186 | } 187 | 188 | auto name = trim_leading_dashes(args_[i]); 189 | 190 | if (!(mode & NO_SPLIT_ON_EQUALSIGN)) 191 | { 192 | auto equalPos = name.find('='); 193 | if (equalPos != std::string::npos) 194 | { 195 | params_.insert({ name.substr(0, equalPos), name.substr(equalPos + 1) }); 196 | continue; 197 | } 198 | } 199 | 200 | // if the option is unregistered and should be a multi-flag 201 | if (1 == (args_[i].size() - name.size()) && // single dash 202 | argh::parser::SINGLE_DASH_IS_MULTIFLAG & mode && // multi-flag mode 203 | !is_param(name)) // unregistered 204 | { 205 | std::string keep_param; 206 | 207 | if (!name.empty() && is_param(std::string(1ul, name.back()))) // last char is param 208 | { 209 | keep_param += name.back(); 210 | name.resize(name.size() - 1); 211 | } 212 | 213 | for (auto const& c : name) 214 | { 215 | flags_.emplace(std::string{ c }); 216 | } 217 | 218 | if (!keep_param.empty()) 219 | { 220 | name = keep_param; 221 | } 222 | else 223 | { 224 | continue; // do not consider other options for this arg 225 | } 226 | } 227 | 228 | // any potential option will get as its value the next arg, unless that arg is an option too 229 | // in that case it will be determined a flag. 230 | if (i == args_.size() - 1 || is_option(args_[i + 1])) 231 | { 232 | flags_.emplace(name); 233 | continue; 234 | } 235 | 236 | // if 'name' is a pre-registered option, then the next arg cannot be a free parameter to it is skipped 237 | // otherwise we have 2 modes: 238 | // PREFER_FLAG_FOR_UNREG_OPTION: a non-registered 'name' is determined a flag. 239 | // The following value (the next arg) will be a free parameter. 240 | // 241 | // PREFER_PARAM_FOR_UNREG_OPTION: a non-registered 'name' is determined a parameter, the next arg 242 | // will be the value of that option. 243 | 244 | assert(!(mode & argh::parser::PREFER_FLAG_FOR_UNREG_OPTION) 245 | || !(mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION)); 246 | 247 | bool preferParam = mode & argh::parser::PREFER_PARAM_FOR_UNREG_OPTION; 248 | 249 | if (is_param(name) || preferParam) 250 | { 251 | params_.insert({ name, args_[i + 1] }); 252 | ++i; // skip next value, it is not a free parameter 253 | continue; 254 | } 255 | else 256 | { 257 | flags_.emplace(name); 258 | } 259 | }; 260 | } 261 | 262 | ////////////////////////////////////////////////////////////////////////// 263 | 264 | inline string_stream parser::bad_stream() const 265 | { 266 | string_stream bad; 267 | bad.setstate(std::ios_base::failbit); 268 | return bad; 269 | } 270 | 271 | ////////////////////////////////////////////////////////////////////////// 272 | 273 | inline bool parser::is_number(std::string const& arg) const 274 | { 275 | // inefficient but simple way to determine if a string is a number (which can start with a '-') 276 | std::istringstream istr(arg); 277 | double number; 278 | istr >> number; 279 | return !(istr.fail() || istr.bad()); 280 | } 281 | 282 | ////////////////////////////////////////////////////////////////////////// 283 | 284 | inline bool parser::is_option(std::string const& arg) const 285 | { 286 | assert(0 != arg.size()); 287 | if (is_number(arg)) 288 | return false; 289 | return '-' == arg[0]; 290 | } 291 | 292 | ////////////////////////////////////////////////////////////////////////// 293 | 294 | inline std::string parser::trim_leading_dashes(std::string const& name) const 295 | { 296 | auto pos = name.find_first_not_of('-'); 297 | return std::string::npos != pos ? name.substr(pos) : name; 298 | } 299 | 300 | ////////////////////////////////////////////////////////////////////////// 301 | 302 | inline bool argh::parser::got_flag(std::string const& name) const 303 | { 304 | return flags_.end() != flags_.find(trim_leading_dashes(name)); 305 | } 306 | 307 | ////////////////////////////////////////////////////////////////////////// 308 | 309 | inline bool argh::parser::is_param(std::string const& name) const 310 | { 311 | return registeredParams_.count(name); 312 | } 313 | 314 | ////////////////////////////////////////////////////////////////////////// 315 | 316 | inline bool parser::operator[](std::string const& name) const 317 | { 318 | return got_flag(name); 319 | } 320 | 321 | ////////////////////////////////////////////////////////////////////////// 322 | 323 | inline bool parser::operator[](std::initializer_list init_list) const 324 | { 325 | return std::any_of(init_list.begin(), init_list.end(), [&](char const* const name) { return got_flag(name); }); 326 | } 327 | 328 | ////////////////////////////////////////////////////////////////////////// 329 | 330 | inline std::string const& parser::operator[](size_t ind) const 331 | { 332 | if (ind < pos_args_.size()) 333 | return pos_args_[ind]; 334 | return empty_; 335 | } 336 | 337 | ////////////////////////////////////////////////////////////////////////// 338 | 339 | inline string_stream parser::operator()(std::string const& name) const 340 | { 341 | auto optIt = params_.find(trim_leading_dashes(name)); 342 | if (params_.end() != optIt) 343 | return string_stream(optIt->second); 344 | return bad_stream(); 345 | } 346 | 347 | ////////////////////////////////////////////////////////////////////////// 348 | 349 | inline string_stream parser::operator()(std::initializer_list init_list) const 350 | { 351 | for (auto& name : init_list) 352 | { 353 | auto optIt = params_.find(trim_leading_dashes(name)); 354 | if (params_.end() != optIt) 355 | return string_stream(optIt->second); 356 | } 357 | return bad_stream(); 358 | } 359 | 360 | ////////////////////////////////////////////////////////////////////////// 361 | 362 | template 363 | string_stream parser::operator()(std::string const& name, T&& def_val) const 364 | { 365 | auto optIt = params_.find(trim_leading_dashes(name)); 366 | if (params_.end() != optIt) 367 | return string_stream(optIt->second); 368 | 369 | std::ostringstream ostr; 370 | ostr << def_val; 371 | return string_stream(ostr.str()); // use default 372 | } 373 | 374 | ////////////////////////////////////////////////////////////////////////// 375 | 376 | // same as above but for a list of names. returns the first value to be found. 377 | template 378 | string_stream parser::operator()(std::initializer_list init_list, T&& def_val) const 379 | { 380 | for (auto& name : init_list) 381 | { 382 | auto optIt = params_.find(trim_leading_dashes(name)); 383 | if (params_.end() != optIt) 384 | return string_stream(optIt->second); 385 | } 386 | std::ostringstream ostr; 387 | ostr << def_val; 388 | return string_stream(ostr.str()); // use default 389 | } 390 | 391 | ////////////////////////////////////////////////////////////////////////// 392 | 393 | inline string_stream parser::operator()(size_t ind) const 394 | { 395 | if (pos_args_.size() <= ind) 396 | return bad_stream(); 397 | 398 | return string_stream(pos_args_[ind]); 399 | } 400 | 401 | ////////////////////////////////////////////////////////////////////////// 402 | 403 | template 404 | string_stream parser::operator()(size_t ind, T&& def_val) const 405 | { 406 | if (pos_args_.size() <= ind) 407 | { 408 | std::ostringstream ostr; 409 | ostr << def_val; 410 | return string_stream(ostr.str()); 411 | } 412 | 413 | return string_stream(pos_args_[ind]); 414 | } 415 | 416 | ////////////////////////////////////////////////////////////////////////// 417 | 418 | inline void parser::add_param(std::string const& name) 419 | { 420 | registeredParams_.insert(trim_leading_dashes(name)); 421 | } 422 | 423 | ////////////////////////////////////////////////////////////////////////// 424 | 425 | inline void parser::add_params(std::initializer_list init_list) 426 | { 427 | for (auto& name : init_list) 428 | registeredParams_.insert(trim_leading_dashes(name)); 429 | } 430 | } 431 | 432 | 433 | -------------------------------------------------------------------------------- /ascreencap-ABitmapLite.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include "ascreencap.h" 3 | #include "ascreencap-ABitmapLite.h" 4 | #include "extern/lz4/lz4.h" 5 | 6 | #define _PIX_FORMAT32_BMP(A,B) \ 7 | { \ 8 | uint32_t pos = A; \ 9 | _dst[(pos + 2)] = *(B) & 0x000000FF; \ 10 | _dst[(pos + 1)] = (*(B) & 0x0000FF00) >> 8; \ 11 | _dst[(pos + 0)] = (*(B) & 0x00FF0000) >> 16; \ 12 | } 13 | 14 | #define _PIX_FORMAT32_SDL(A,B) \ 15 | { \ 16 | uint32_t pos = A; \ 17 | _dst[(pos + 0)] = (*(B) & 0xFF000000) >> 24; \ 18 | _dst[(pos + 1)] = (*(B) & 0x00FF0000) >> 16; \ 19 | _dst[(pos + 2)] = (*(B) & 0x0000FF00) >> 8; \ 20 | } 21 | 22 | #define _PIX_FORMAT16_BMP(A,B) \ 23 | { \ 24 | uint32_t pos = A; \ 25 | _dst[(pos + 2)] = (255 * (*(B) & 0x001F))/32; \ 26 | _dst[(pos + 1)] = (255 * ((*(B) & 0x07E0) >> 5))/64; \ 27 | _dst[(pos + 0)] = (255 * ((*(B) & 0xF800) >> 11))/32; \ 28 | } 29 | 30 | #define _PIX_FORMAT16_SDL(A,B) \ 31 | { \ 32 | uint32_t pos = A; \ 33 | _dst[(pos + 2)] = (255 * ((*(B) & 0xF800) >> 11))/32; \ 34 | _dst[(pos + 1)] = (255 * ((*(B) & 0x07E0) >> 5))/64; \ 35 | _dst[(pos + 0)] = (255 * (*(B) & 0x001F))/32; \ 36 | } 37 | 38 | 39 | namespace ACapture 40 | { 41 | 42 | ABitmapLite::ABitmapLite() 43 | : ishead(false), issdlcompat(false), rat(0U), rot(0U) {} 44 | 45 | ABitmapLite::ABitmapLite( 46 | uint32_t _w, uint32_t _h, uint32_t _s, uint32_t _f, const void *_src, size_t _sz 47 | ) : ishead(false), issdlcompat(false), rat(0U), rot(0U) 48 | { 49 | SetData(_w, _h, _s, _f, _src, _sz); 50 | } 51 | 52 | ABitmapLite::~ABitmapLite() {} 53 | 54 | bool ABitmapLite::TestData(bool issrc) 55 | { 56 | return !( 57 | (!bmpdata.w) || 58 | (!bmpdata.h) || 59 | (!bmpdata.s) || 60 | (!bmpdata.sz) || 61 | ((issrc) && (!bmpdata.src)) 62 | ); 63 | } 64 | 65 | void ABitmapLite::Reset() 66 | { 67 | ::memset(&bmpdata, 0, sizeof(bmpdata)); 68 | ishead = false; 69 | 70 | if (vsrc.size()) 71 | vsrc.clear(); 72 | if (vdst.size()) 73 | vdst.clear(); 74 | if (vdstz.size()) 75 | vdstz.clear(); 76 | } 77 | 78 | void ABitmapLite::SetData( 79 | uint32_t _w, uint32_t _h, uint32_t _s, uint32_t _f, const void *_src, size_t _sz 80 | ) 81 | { 82 | bmpdata.w = _w; 83 | bmpdata.h = _h; 84 | bmpdata.s = _s; 85 | bmpdata.f = _f; 86 | bmpdata.sz = _sz; 87 | 88 | if (TestData(false)) 89 | { 90 | bmpdata.b = (bmpdata.sz / bmpdata.w / bmpdata.h); 91 | SetData(_src, _sz); 92 | } 93 | } 94 | 95 | void ABitmapLite::SetData(const void *_src, size_t _sz) 96 | { 97 | uint8_t *l_src = static_cast( 98 | const_cast(_src) 99 | ); 100 | vsrc.assign(&l_src[0], &l_src[0] + _sz); 101 | bmpdata.sz = _sz; 102 | bmpdata.src = &vsrc[0]; 103 | bmpdata.dst = nullptr; 104 | } 105 | 106 | uint8_t * ABitmapLite::GetData(size_t *psz) 107 | { 108 | do 109 | { 110 | *psz = 0U; 111 | 112 | if (!TestData(true)) 113 | break; 114 | 115 | if (!convertBmp(issdlcompat)) 116 | break; 117 | 118 | if (!issdlcompat) 119 | if (!headerBmp()) 120 | break; 121 | 122 | *psz = ((ishead) ? 123 | (bmpdata.sz + sizeof(ABitmapLite::BMPHEADER)) : bmpdata.sz 124 | ); 125 | return ((ishead) ? 126 | &bmpdata.dst[0] : &bmpdata.dst[sizeof(ABitmapLite::BMPHEADER)] 127 | ); 128 | } 129 | while (0); 130 | 131 | return nullptr; 132 | } 133 | 134 | uint8_t * ABitmapLite::GetDataPack(size_t *psz, int32_t fast) 135 | { 136 | do 137 | { 138 | uint8_t *pdst; 139 | 140 | if ( 141 | (!(pdst = GetData(psz))) || 142 | (!*psz) 143 | ) 144 | break; 145 | 146 | int lzrsz, 147 | lzbsz = LZ4_compressBound(static_cast(*psz)); 148 | 149 | if (!lzbsz) 150 | break; 151 | 152 | vdstz.resize(lzbsz + sizeof(STREAMHEADER)); 153 | 154 | lzrsz = LZ4_compress_fast( 155 | (const char*)pdst, 156 | (char*)&vdstz[sizeof(STREAMHEADER)], 157 | static_cast(*psz), 158 | lzbsz, 159 | fast 160 | ); 161 | 162 | if (lzrsz <= 0) 163 | break; 164 | 165 | vdstz.resize(lzrsz + sizeof(STREAMHEADER)); 166 | 167 | STREAMHEADER sh = { 168 | BMZ_MAGIC, 169 | static_cast(*psz), 170 | static_cast(lzrsz), 171 | bmpdata.w, 172 | bmpdata.h 173 | }; 174 | memcpy(&vdstz[0], &sh, sizeof(sh)); 175 | 176 | *psz = vdstz.size(); 177 | bmpdata.dst = &vdstz[0]; 178 | return &bmpdata.dst[0]; 179 | } 180 | while (0); 181 | 182 | *psz = 0U; 183 | return nullptr; 184 | } 185 | 186 | uint32_t ABitmapLite::getBpp() const 187 | { 188 | /// TODO: format normalize 189 | switch(bmpdata.f) 190 | { 191 | /// * 32 BPP 192 | case android::PIXEL_FORMAT_RGBA_8888: 193 | case android::PIXEL_FORMAT_RGBX_8888: 194 | case android::PIXEL_FORMAT_BGRA_8888: 195 | /// > 5.1.1 duplicate PIXEL_FORMAT_RGBA_8888 196 | //case android::PIXEL_FORMAT_sRGB_A_8888: 197 | /// 5.1.1 AOSP 198 | //case android::PIXEL_FORMAT_sRGB_X_8888: 199 | return 32; 200 | /// * 24 BPP 201 | case android::PIXEL_FORMAT_RGB_888: 202 | return 24; 203 | /// * 16 BPP 204 | case android::PIXEL_FORMAT_RGB_565: 205 | case android::PIXEL_FORMAT_RGBA_5551: 206 | case android::PIXEL_FORMAT_RGBA_4444: 207 | return 16; 208 | default: return 0; 209 | } 210 | } 211 | 212 | uint32_t ABitmapLite::getPadDst(uint32_t _w) const 213 | { 214 | uint32_t pad = 0U; 215 | while (((_w + pad) % 4) != 0) 216 | pad++; 217 | return pad; 218 | } 219 | 220 | uint32_t ABitmapLite::getPadSrc() const 221 | { 222 | return ((bmpdata.s > bmpdata.w) ? 223 | static_cast((bmpdata.s - bmpdata.w) * bmpdata.b) : 224 | 0U 225 | ); 226 | } 227 | 228 | bool ABitmapLite::convertBmp(bool sdlcompat) 229 | { 230 | if (!bmpdata.src) 231 | return false; 232 | 233 | const uint32_t 234 | hd = bmpdata.h, 235 | wr = ((rat) ? __extension__ ( 236 | { uint32_t a = (bmpdata.w / rat); 237 | if (bmpdata.w % rat) a++; a; }) 238 | : bmpdata.w), 239 | hr = ((rat) ? __extension__ ( 240 | { uint32_t a = (bmpdata.h / rat); 241 | if (bmpdata.h % rat) a++; a; }) 242 | : bmpdata.h), 243 | ar = ((rat) ? rat : 1U), 244 | ax = (ar * bmpdata.b), 245 | br = bmpdata.b, 246 | wsz = (bmpdata.w * bmpdata.b), 247 | wdz = (wr * 3U), 248 | pfmt = getBpp(), 249 | spad = getPadSrc(), 250 | dpad = getPadDst(wdz); 251 | 252 | 253 | if (!pfmt) 254 | return false; 255 | 256 | bmpdata.w = ((rat) ? wr : bmpdata.w); 257 | bmpdata.h = ((rat) ? hr : bmpdata.h); 258 | bmpdata.sz = ((wdz + dpad) * hr); 259 | 260 | if (!sdlcompat) 261 | { 262 | std::reverse(vsrc.begin(), vsrc.end()); 263 | bmpdata.src = &vsrc[0]; 264 | } 265 | 266 | # if defined(_DEBUG) 267 | __LOG_PRINT("-> convertBmp -> point: %ux%u", bmpdata.w, bmpdata.h); 268 | __LOG_PRINT("-> convertBmp -> sdl/ratio/rotate: %d/%u/%u", sdlcompat, rat, rot); 269 | __LOG_PRINT("-> convertBmp -> format/bpp: %u/%u", pfmt, bmpdata.b); 270 | __LOG_PRINT("-> convertBmp -> wsz/wdz/pads: %u/%u/%u/%u", wsz, wdz, spad, dpad); 271 | __LOG_PRINT("-> convertBmp -> size: %zu", bmpdata.sz); 272 | # endif 273 | 274 | vdst.resize(bmpdata.sz + sizeof(ABitmapLite::BMPHEADER)); 275 | bmpdata.dst = &vdst[0]; 276 | uint8_t *_dst = &vdst[sizeof(ABitmapLite::BMPHEADER)]; 277 | uint32_t y; 278 | 279 | # pragma omp parallel for private(y) schedule(static) 280 | for(y = 0U; y < hd; y += ar) 281 | { 282 | uint32_t sx = 0U, ssz = ((wsz + spad) * y), 283 | dx = 0U, dsz = ((y / ar) * (wdz + dpad)); 284 | 285 | std::vector v(wsz + spad); 286 | v.assign( 287 | &bmpdata.src[ssz], 288 | &bmpdata.src[(ssz + wsz + spad)] 289 | ); 290 | std::reverse(v.begin(), v.end()); 291 | 292 | if ((!rat) && (pfmt == 24)) 293 | { 294 | /// TODO: sdl2 format make 295 | memcpy(&_dst[dsz], &v[0], v.size()); 296 | continue; 297 | } 298 | 299 | for (; sx < v.size(); sx += ax, dx += 3U) 300 | { 301 | switch (pfmt) 302 | { 303 | case 16: 304 | { 305 | uint16_t *pixel16 = (uint16_t*)(&v[sx]); 306 | if (sdlcompat) 307 | _PIX_FORMAT16_SDL((dsz + dx), pixel16) 308 | else 309 | _PIX_FORMAT16_BMP((dsz + dx), pixel16) 310 | break; 311 | } 312 | case 24: 313 | { 314 | /// TODO: sdl2 format make 315 | memcpy(&_dst[(dsz + dx)], &v[sx], br); 316 | break; 317 | } 318 | case 32: 319 | { 320 | uint32_t *pixel32 = (uint32_t*)(&v[sx]); 321 | if (sdlcompat) 322 | _PIX_FORMAT32_SDL((dsz + dx), pixel32) 323 | else 324 | _PIX_FORMAT32_BMP((dsz + dx), pixel32) 325 | break; 326 | } 327 | } 328 | } 329 | } 330 | if (rot) 331 | rotateBmp(rot); 332 | 333 | # if defined(_DEBUG_RAW_FILE) 334 | FILE *fp; 335 | static const char *fnameraw = "/data/local/tmp/OutBmp.raw"; 336 | __LOG_PRINT("-> convertBmp -> write debug RAW file: %s", fnameraw); 337 | if ((fp = fopen(fnameraw, "w"))) 338 | { 339 | int sraw = fwrite(_dst, 1, bmpdata.sz, fp); 340 | fclose(fp); 341 | __LOG_PRINT("-> convertBmp -> wrote to file: %d/%u bytes.", sraw, bmpdata.sz); 342 | } 343 | # endif 344 | 345 | return true; 346 | } 347 | 348 | void ABitmapLite::rotateBmp(uint32_t angle) 349 | { 350 | switch (angle) 351 | { 352 | case 90: 353 | case 180: 354 | case 270: 355 | case 360: /// mirror mode 356 | { 357 | if (!bmpdata.dst) 358 | return; 359 | break; 360 | } 361 | default: 362 | return; 363 | } 364 | 365 | uint32_t y, spad, dpad, ssz; 366 | const uint32_t wr = bmpdata.w, hr = bmpdata.h; 367 | 368 | switch (angle) 369 | { 370 | case 90: 371 | case 270: 372 | case 360: 373 | { 374 | spad = getPadDst(wr); 375 | dpad = getPadDst(hr); 376 | ssz = (((wr * 3U) + dpad) * hr); 377 | break; 378 | } 379 | default: 380 | { 381 | spad = dpad = getPadDst(wr); 382 | ssz = bmpdata.sz; 383 | break; 384 | } 385 | break; 386 | } 387 | 388 | std::vector v(ssz + sizeof(ABitmapLite::BMPHEADER)); 389 | const uint8_t *p0 = &bmpdata.dst[sizeof(ABitmapLite::BMPHEADER)]; 390 | uint8_t *p1 = &v[sizeof(ABitmapLite::BMPHEADER)]; 391 | 392 | # pragma omp parallel for private(y) schedule(dynamic) 393 | for (y = 0U; y < hr; y++) 394 | { 395 | uint32_t sx, dx; 396 | 397 | switch (angle) 398 | { 399 | case 90: 400 | { 401 | dx = (hr - y - 1) + (y * dpad); 402 | sx = ((y) ? ((wr + spad) * y) : wr); 403 | break; 404 | } 405 | case 180: 406 | { 407 | dx = ((wr + dpad) * y); 408 | sx = ((hr - y - 1) * (wr + spad)); 409 | break; 410 | } 411 | case 270: // TODO: 412 | { 413 | dx = y + (y * dpad); 414 | sx = ((wr + spad) * y); 415 | break; 416 | } 417 | case 360: 418 | { 419 | dx = y + (y * dpad); 420 | sx = ((wr + spad) * y); 421 | break; 422 | } 423 | default: 424 | { 425 | continue; 426 | } 427 | } 428 | 429 | for (uint32_t x = 0U; x < wr; x++) 430 | { 431 | uint32_t ssz, dsz; 432 | 433 | switch (angle) 434 | { 435 | case 90: 436 | case 360: 437 | { 438 | dsz = (((hr * x) + dx) * 3); 439 | ssz = ((sx + x) * 3); 440 | break; 441 | } 442 | case 180: 443 | { 444 | dsz = ((dx + x) * 3); 445 | ssz = ((sx + (wr - x - 1)) * 3); 446 | break; 447 | } 448 | case 270: // TODO: 449 | { 450 | dsz = (((hr * x) + dx) * 3); 451 | ssz = ((sx + x) * 3); 452 | break; 453 | } 454 | default: 455 | { 456 | continue; 457 | } 458 | } 459 | 460 | p1[dsz + 0] = p0[ssz + 0]; 461 | p1[dsz + 1] = p0[ssz + 1]; 462 | p1[dsz + 2] = p0[ssz + 2]; 463 | } 464 | } 465 | 466 | vdst.clear(); 467 | vdst.assign(v.begin(), v.end()); 468 | bmpdata.dst = &vdst[0]; 469 | 470 | switch (angle) 471 | { 472 | case 90: 473 | case 270: 474 | case 360: 475 | { 476 | if (bmpdata.w != bmpdata.h) 477 | std::swap(bmpdata.w, bmpdata.h); 478 | break; 479 | } 480 | default: 481 | break; 482 | } 483 | } 484 | 485 | bool ABitmapLite::headerBmp() 486 | { 487 | if (!bmpdata.sz) 488 | return false; 489 | 490 | ABitmapLite::BMPHEADER bmph{}; 491 | 492 | bmph.fh.bfType = 0x4D42; // "BM" 493 | bmph.fh.bfSize = bmpdata.sz + sizeof(bmph); 494 | bmph.fh.bfOffBits = sizeof(bmph); 495 | bmph.ih.biSize = sizeof(bmph.ih); 496 | bmph.ih.biWidth = static_cast(bmpdata.w); 497 | bmph.ih.biHeight = static_cast(bmpdata.h); 498 | bmph.ih.biPlanes = 1U; 499 | bmph.ih.biBitCount = 24; //(b * 8); 500 | bmph.ih.biCompression = 0x0000; // BI_RGB 501 | bmph.ih.biSizeImage = 0; 502 | 503 | if (!memcpy(&bmpdata.dst[0], &bmph, sizeof(bmph))) 504 | return false; 505 | 506 | ishead = true; 507 | 508 | # if defined(_DEBUG) 509 | __LOG_PRINT("-> bmph -> point: %ux%u", bmpdata.w, bmpdata.h); 510 | __LOG_PRINT("-> bmph -> size: %u/%zu", bmph.fh.bfSize, bmpdata.sz); 511 | # endif 512 | return true; 513 | } 514 | 515 | } 516 | -------------------------------------------------------------------------------- /extern/lz4/lz4.h: -------------------------------------------------------------------------------- 1 | /* 2 | * LZ4 - Fast LZ compression algorithm 3 | * Header File 4 | * Copyright (C) 2011-present, Yann Collet. 5 | 6 | BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php) 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are 10 | met: 11 | 12 | * Redistributions of source code must retain the above copyright 13 | notice, this list of conditions and the following disclaimer. 14 | * Redistributions in binary form must reproduce the above 15 | copyright notice, this list of conditions and the following disclaimer 16 | in the documentation and/or other materials provided with the 17 | distribution. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | 31 | You can contact the author at : 32 | - LZ4 homepage : http://www.lz4.org 33 | - LZ4 source repository : https://github.com/lz4/lz4 34 | */ 35 | #if defined (__cplusplus) 36 | extern "C" { 37 | #endif 38 | 39 | #ifndef LZ4_H_2983827168210 40 | #define LZ4_H_2983827168210 41 | 42 | /* --- Dependency --- */ 43 | #include /* size_t */ 44 | 45 | 46 | /** 47 | Introduction 48 | 49 | LZ4 is lossless compression algorithm, providing compression speed at 500 MB/s per core, 50 | scalable with multi-cores CPU. It features an extremely fast decoder, with speed in 51 | multiple GB/s per core, typically reaching RAM speed limits on multi-core systems. 52 | 53 | The LZ4 compression library provides in-memory compression and decompression functions. 54 | Compression can be done in: 55 | - a single step (described as Simple Functions) 56 | - a single step, reusing a context (described in Advanced Functions) 57 | - unbounded multiple steps (described as Streaming compression) 58 | 59 | lz4.h provides block compression functions. It gives full buffer control to user. 60 | Decompressing an lz4-compressed block also requires metadata (such as compressed size). 61 | Each application is free to encode such metadata in whichever way it wants. 62 | 63 | An additional format, called LZ4 frame specification (doc/lz4_Frame_format.md), 64 | take care of encoding standard metadata alongside LZ4-compressed blocks. 65 | Frame format is required for interoperability. 66 | It is delivered through a companion API, declared in lz4frame.h. 67 | */ 68 | 69 | /*^*************************************************************** 70 | * Export parameters 71 | *****************************************************************/ 72 | /* 73 | * LZ4_DLL_EXPORT : 74 | * Enable exporting of functions when building a Windows DLL 75 | * LZ4LIB_VISIBILITY : 76 | * Control library symbols visibility. 77 | */ 78 | #ifndef LZ4LIB_VISIBILITY 79 | # if defined(__GNUC__) && (__GNUC__ >= 4) 80 | # define LZ4LIB_VISIBILITY __attribute__ ((visibility ("default"))) 81 | # else 82 | # define LZ4LIB_VISIBILITY 83 | # endif 84 | #endif 85 | #if defined(LZ4_DLL_EXPORT) && (LZ4_DLL_EXPORT==1) 86 | # define LZ4LIB_API __declspec(dllexport) LZ4LIB_VISIBILITY 87 | #elif defined(LZ4_DLL_IMPORT) && (LZ4_DLL_IMPORT==1) 88 | # define LZ4LIB_API __declspec(dllimport) LZ4LIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/ 89 | #else 90 | # define LZ4LIB_API LZ4LIB_VISIBILITY 91 | #endif 92 | 93 | /*------ Version ------*/ 94 | #define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */ 95 | #define LZ4_VERSION_MINOR 8 /* for new (non-breaking) interface capabilities */ 96 | #define LZ4_VERSION_RELEASE 3 /* for tweaks, bug-fixes, or development */ 97 | 98 | #define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE) 99 | 100 | #define LZ4_LIB_VERSION LZ4_VERSION_MAJOR.LZ4_VERSION_MINOR.LZ4_VERSION_RELEASE 101 | #define LZ4_QUOTE(str) #str 102 | #define LZ4_EXPAND_AND_QUOTE(str) LZ4_QUOTE(str) 103 | #define LZ4_VERSION_STRING LZ4_EXPAND_AND_QUOTE(LZ4_LIB_VERSION) 104 | 105 | LZ4LIB_API int LZ4_versionNumber (void); /**< library version number; useful to check dll version */ 106 | LZ4LIB_API const char* LZ4_versionString (void); /**< library version string; useful to check dll version */ 107 | 108 | 109 | /*-************************************ 110 | * Tuning parameter 111 | **************************************/ 112 | /*! 113 | * LZ4_MEMORY_USAGE : 114 | * Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.) 115 | * Increasing memory usage improves compression ratio. 116 | * Reduced memory usage may improve speed, thanks to better cache locality. 117 | * Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache 118 | */ 119 | #ifndef LZ4_MEMORY_USAGE 120 | # define LZ4_MEMORY_USAGE 14 121 | #endif 122 | 123 | 124 | /*-************************************ 125 | * Simple Functions 126 | **************************************/ 127 | /*! LZ4_compress_default() : 128 | Compresses 'srcSize' bytes from buffer 'src' 129 | into already allocated 'dst' buffer of size 'dstCapacity'. 130 | Compression is guaranteed to succeed if 'dstCapacity' >= LZ4_compressBound(srcSize). 131 | It also runs faster, so it's a recommended setting. 132 | If the function cannot compress 'src' into a more limited 'dst' budget, 133 | compression stops *immediately*, and the function result is zero. 134 | In which case, 'dst' content is undefined (invalid). 135 | srcSize : max supported value is LZ4_MAX_INPUT_SIZE. 136 | dstCapacity : size of buffer 'dst' (which must be already allocated) 137 | @return : the number of bytes written into buffer 'dst' (necessarily <= dstCapacity) 138 | or 0 if compression fails 139 | Note : This function is protected against buffer overflow scenarios (never writes outside 'dst' buffer, nor read outside 'source' buffer). 140 | */ 141 | LZ4LIB_API int LZ4_compress_default(const char* src, char* dst, int srcSize, int dstCapacity); 142 | 143 | /*! LZ4_decompress_safe() : 144 | compressedSize : is the exact complete size of the compressed block. 145 | dstCapacity : is the size of destination buffer, which must be already allocated. 146 | @return : the number of bytes decompressed into destination buffer (necessarily <= dstCapacity) 147 | If destination buffer is not large enough, decoding will stop and output an error code (negative value). 148 | If the source stream is detected malformed, the function will stop decoding and return a negative result. 149 | Note : This function is protected against malicious data packets (never writes outside 'dst' buffer, nor read outside 'source' buffer). 150 | */ 151 | LZ4LIB_API int LZ4_decompress_safe (const char* src, char* dst, int compressedSize, int dstCapacity); 152 | 153 | 154 | /*-************************************ 155 | * Advanced Functions 156 | **************************************/ 157 | #define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */ 158 | #define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16) 159 | 160 | /*! LZ4_compressBound() : 161 | Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible) 162 | This function is primarily useful for memory allocation purposes (destination buffer size). 163 | Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example). 164 | Note that LZ4_compress_default() compresses faster when dstCapacity is >= LZ4_compressBound(srcSize) 165 | inputSize : max supported value is LZ4_MAX_INPUT_SIZE 166 | return : maximum output size in a "worst case" scenario 167 | or 0, if input size is incorrect (too large or negative) 168 | */ 169 | LZ4LIB_API int LZ4_compressBound(int inputSize); 170 | 171 | /*! LZ4_compress_fast() : 172 | Same as LZ4_compress_default(), but allows selection of "acceleration" factor. 173 | The larger the acceleration value, the faster the algorithm, but also the lesser the compression. 174 | It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed. 175 | An acceleration value of "1" is the same as regular LZ4_compress_default() 176 | Values <= 0 will be replaced by ACCELERATION_DEFAULT (currently == 1, see lz4.c). 177 | */ 178 | LZ4LIB_API int LZ4_compress_fast (const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); 179 | 180 | 181 | /*! LZ4_compress_fast_extState() : 182 | * Same as LZ4_compress_fast(), using an externally allocated memory space for its state. 183 | * Use LZ4_sizeofState() to know how much memory must be allocated, 184 | * and allocate it on 8-bytes boundaries (using `malloc()` typically). 185 | * Then, provide this buffer as `void* state` to compression function. 186 | */ 187 | LZ4LIB_API int LZ4_sizeofState(void); 188 | LZ4LIB_API int LZ4_compress_fast_extState (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); 189 | 190 | 191 | /*! LZ4_compress_destSize() : 192 | * Reverse the logic : compresses as much data as possible from 'src' buffer 193 | * into already allocated buffer 'dst', of size >= 'targetDestSize'. 194 | * This function either compresses the entire 'src' content into 'dst' if it's large enough, 195 | * or fill 'dst' buffer completely with as much data as possible from 'src'. 196 | * note: acceleration parameter is fixed to "default". 197 | * 198 | * *srcSizePtr : will be modified to indicate how many bytes where read from 'src' to fill 'dst'. 199 | * New value is necessarily <= input value. 200 | * @return : Nb bytes written into 'dst' (necessarily <= targetDestSize) 201 | * or 0 if compression fails. 202 | */ 203 | LZ4LIB_API int LZ4_compress_destSize (const char* src, char* dst, int* srcSizePtr, int targetDstSize); 204 | 205 | 206 | /*! LZ4_decompress_fast() : **unsafe!** 207 | * This function used to be a bit faster than LZ4_decompress_safe(), 208 | * though situation has changed in recent versions, 209 | * and now `LZ4_decompress_safe()` can be as fast and sometimes faster than `LZ4_decompress_fast()`. 210 | * Moreover, LZ4_decompress_fast() is not protected vs malformed input, as it doesn't perform full validation of compressed data. 211 | * As a consequence, this function is no longer recommended, and may be deprecated in future versions. 212 | * It's last remaining specificity is that it can decompress data without knowing its compressed size. 213 | * 214 | * originalSize : is the uncompressed size to regenerate. 215 | * `dst` must be already allocated, its size must be >= 'originalSize' bytes. 216 | * @return : number of bytes read from source buffer (== compressed size). 217 | * If the source stream is detected malformed, the function stops decoding and returns a negative result. 218 | * note : This function requires uncompressed originalSize to be known in advance. 219 | * The function never writes past the output buffer. 220 | * However, since it doesn't know its 'src' size, it may read past the intended input. 221 | * Also, because match offsets are not validated during decoding, 222 | * reads from 'src' may underflow. 223 | * Use this function in trusted environment **only**. 224 | */ 225 | LZ4LIB_API int LZ4_decompress_fast (const char* src, char* dst, int originalSize); 226 | 227 | /*! LZ4_decompress_safe_partial() : 228 | * Decompress an LZ4 compressed block, of size 'srcSize' at position 'src', 229 | * into destination buffer 'dst' of size 'dstCapacity'. 230 | * Up to 'targetOutputSize' bytes will be decoded. 231 | * The function stops decoding on reaching this objective, 232 | * which can boost performance when only the beginning of a block is required. 233 | * 234 | * @return : the number of bytes decoded in `dst` (necessarily <= dstCapacity) 235 | * If source stream is detected malformed, function returns a negative result. 236 | * 237 | * Note : @return can be < targetOutputSize, if compressed block contains less data. 238 | * 239 | * Note 2 : this function features 2 parameters, targetOutputSize and dstCapacity, 240 | * and expects targetOutputSize <= dstCapacity. 241 | * It effectively stops decoding on reaching targetOutputSize, 242 | * so dstCapacity is kind of redundant. 243 | * This is because in a previous version of this function, 244 | * decoding operation would not "break" a sequence in the middle. 245 | * As a consequence, there was no guarantee that decoding would stop at exactly targetOutputSize, 246 | * it could write more bytes, though only up to dstCapacity. 247 | * Some "margin" used to be required for this operation to work properly. 248 | * This is no longer necessary. 249 | * The function nonetheless keeps its signature, in an effort to not break API. 250 | */ 251 | LZ4LIB_API int LZ4_decompress_safe_partial (const char* src, char* dst, int srcSize, int targetOutputSize, int dstCapacity); 252 | 253 | 254 | /*-********************************************* 255 | * Streaming Compression Functions 256 | ***********************************************/ 257 | typedef union LZ4_stream_u LZ4_stream_t; /* incomplete type (defined later) */ 258 | 259 | LZ4LIB_API LZ4_stream_t* LZ4_createStream(void); 260 | LZ4LIB_API int LZ4_freeStream (LZ4_stream_t* streamPtr); 261 | 262 | /*! LZ4_resetStream() : 263 | * An LZ4_stream_t structure can be allocated once and re-used multiple times. 264 | * Use this function to start compressing a new stream. 265 | */ 266 | LZ4LIB_API void LZ4_resetStream (LZ4_stream_t* streamPtr); 267 | 268 | /*! LZ4_loadDict() : 269 | * Use this function to load a static dictionary into LZ4_stream_t. 270 | * Any previous data will be forgotten, only 'dictionary' will remain in memory. 271 | * Loading a size of 0 is allowed, and is the same as reset. 272 | * @return : dictionary size, in bytes (necessarily <= 64 KB) 273 | */ 274 | LZ4LIB_API int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize); 275 | 276 | /*! LZ4_compress_fast_continue() : 277 | * Compress 'src' content using data from previously compressed blocks, for better compression ratio. 278 | * 'dst' buffer must be already allocated. 279 | * If dstCapacity >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster. 280 | * 281 | * @return : size of compressed block 282 | * or 0 if there is an error (typically, cannot fit into 'dst'). 283 | * 284 | * Note 1 : Each invocation to LZ4_compress_fast_continue() generates a new block. 285 | * Each block has precise boundaries. 286 | * Each block must be decompressed separately, calling LZ4_decompress_*() with relevant metadata. 287 | * It's not possible to append blocks together and expect a single invocation of LZ4_decompress_*() to decompress them together. 288 | * 289 | * Note 2 : The previous 64KB of source data is __assumed__ to remain present, unmodified, at same address in memory ! 290 | * 291 | * Note 3 : When input is structured as a double-buffer, each buffer can have any size, including < 64 KB. 292 | * Make sure that buffers are separated, by at least one byte. 293 | * This construction ensures that each block only depends on previous block. 294 | * 295 | * Note 4 : If input buffer is a ring-buffer, it can have any size, including < 64 KB. 296 | * 297 | * Note 5 : After an error, the stream status is undefined (invalid), it can only be reset or freed. 298 | */ 299 | LZ4LIB_API int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); 300 | 301 | /*! LZ4_saveDict() : 302 | * If last 64KB data cannot be guaranteed to remain available at its current memory location, 303 | * save it into a safer place (char* safeBuffer). 304 | * This is schematically equivalent to a memcpy() followed by LZ4_loadDict(), 305 | * but is much faster, because LZ4_saveDict() doesn't need to rebuild tables. 306 | * @return : saved dictionary size in bytes (necessarily <= maxDictSize), or 0 if error. 307 | */ 308 | LZ4LIB_API int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int maxDictSize); 309 | 310 | 311 | /*-********************************************** 312 | * Streaming Decompression Functions 313 | * Bufferless synchronous API 314 | ************************************************/ 315 | typedef union LZ4_streamDecode_u LZ4_streamDecode_t; /* tracking context */ 316 | 317 | /*! LZ4_createStreamDecode() and LZ4_freeStreamDecode() : 318 | * creation / destruction of streaming decompression tracking context. 319 | * A tracking context can be re-used multiple times. 320 | */ 321 | LZ4LIB_API LZ4_streamDecode_t* LZ4_createStreamDecode(void); 322 | LZ4LIB_API int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream); 323 | 324 | /*! LZ4_setStreamDecode() : 325 | * An LZ4_streamDecode_t context can be allocated once and re-used multiple times. 326 | * Use this function to start decompression of a new stream of blocks. 327 | * A dictionary can optionally be set. Use NULL or size 0 for a reset order. 328 | * Dictionary is presumed stable : it must remain accessible and unmodified during next decompression. 329 | * @return : 1 if OK, 0 if error 330 | */ 331 | LZ4LIB_API int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize); 332 | 333 | /*! LZ4_decoderRingBufferSize() : v1.8.2+ 334 | * Note : in a ring buffer scenario (optional), 335 | * blocks are presumed decompressed next to each other 336 | * up to the moment there is not enough remaining space for next block (remainingSize < maxBlockSize), 337 | * at which stage it resumes from beginning of ring buffer. 338 | * When setting such a ring buffer for streaming decompression, 339 | * provides the minimum size of this ring buffer 340 | * to be compatible with any source respecting maxBlockSize condition. 341 | * @return : minimum ring buffer size, 342 | * or 0 if there is an error (invalid maxBlockSize). 343 | */ 344 | LZ4LIB_API int LZ4_decoderRingBufferSize(int maxBlockSize); 345 | #define LZ4_DECODER_RING_BUFFER_SIZE(maxBlockSize) (65536 + 14 + (maxBlockSize)) /* for static allocation; maxBlockSize presumed valid */ 346 | 347 | /*! LZ4_decompress_*_continue() : 348 | * These decoding functions allow decompression of consecutive blocks in "streaming" mode. 349 | * A block is an unsplittable entity, it must be presented entirely to a decompression function. 350 | * Decompression functions only accepts one block at a time. 351 | * The last 64KB of previously decoded data *must* remain available and unmodified at the memory position where they were decoded. 352 | * If less than 64KB of data has been decoded, all the data must be present. 353 | * 354 | * Special : if decompression side sets a ring buffer, it must respect one of the following conditions : 355 | * - Decompression buffer size is _at least_ LZ4_decoderRingBufferSize(maxBlockSize). 356 | * maxBlockSize is the maximum size of any single block. It can have any value > 16 bytes. 357 | * In which case, encoding and decoding buffers do not need to be synchronized. 358 | * Actually, data can be produced by any source compliant with LZ4 format specification, and respecting maxBlockSize. 359 | * - Synchronized mode : 360 | * Decompression buffer size is _exactly_ the same as compression buffer size, 361 | * and follows exactly same update rule (block boundaries at same positions), 362 | * and decoding function is provided with exact decompressed size of each block (exception for last block of the stream), 363 | * _then_ decoding & encoding ring buffer can have any size, including small ones ( < 64 KB). 364 | * - Decompression buffer is larger than encoding buffer, by a minimum of maxBlockSize more bytes. 365 | * In which case, encoding and decoding buffers do not need to be synchronized, 366 | * and encoding ring buffer can have any size, including small ones ( < 64 KB). 367 | * 368 | * Whenever these conditions are not possible, 369 | * save the last 64KB of decoded data into a safe buffer where it can't be modified during decompression, 370 | * then indicate where this data is saved using LZ4_setStreamDecode(), before decompressing next block. 371 | */ 372 | LZ4LIB_API int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int srcSize, int dstCapacity); 373 | LZ4LIB_API int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* src, char* dst, int originalSize); 374 | 375 | 376 | /*! LZ4_decompress_*_usingDict() : 377 | * These decoding functions work the same as 378 | * a combination of LZ4_setStreamDecode() followed by LZ4_decompress_*_continue() 379 | * They are stand-alone, and don't need an LZ4_streamDecode_t structure. 380 | * Dictionary is presumed stable : it must remain accessible and unmodified during decompression. 381 | * Performance tip : Decompression speed can be substantially increased 382 | * when dst == dictStart + dictSize. 383 | */ 384 | LZ4LIB_API int LZ4_decompress_safe_usingDict (const char* src, char* dst, int srcSize, int dstCapcity, const char* dictStart, int dictSize); 385 | LZ4LIB_API int LZ4_decompress_fast_usingDict (const char* src, char* dst, int originalSize, const char* dictStart, int dictSize); 386 | 387 | 388 | /*^************************************* 389 | * !!!!!! STATIC LINKING ONLY !!!!!! 390 | ***************************************/ 391 | 392 | /*-**************************************************************************** 393 | * Symbols declared in this section must be considered unstable. Their 394 | * signatures or semantics may change, or they may be removed altogether in the 395 | * future. They are therefore only safe to depend on when the caller is 396 | * statically linked against the library. 397 | * 398 | * To protect against unsafe usage, not only are the declarations guarded, the 399 | * definitions are hidden by default when building LZ4 as a shared/dynamic 400 | * library. 401 | * 402 | * In order to access these declarations, define LZ4_STATIC_LINKING_ONLY in 403 | * your application before including LZ4's headers. 404 | * 405 | * In order to make their implementations accessible dynamically, you must 406 | * define LZ4_PUBLISH_STATIC_FUNCTIONS when building the LZ4 library. 407 | ******************************************************************************/ 408 | 409 | #ifdef LZ4_PUBLISH_STATIC_FUNCTIONS 410 | #define LZ4LIB_STATIC_API LZ4LIB_API 411 | #else 412 | #define LZ4LIB_STATIC_API 413 | #endif 414 | 415 | #ifdef LZ4_STATIC_LINKING_ONLY 416 | 417 | /*! LZ4_resetStream_fast() : 418 | * Use this to prepare a context for a new chain of calls to a streaming API 419 | * (e.g., LZ4_compress_fast_continue()). 420 | * 421 | * Note: 422 | * To stay on the safe side, when LZ4_stream_t is used for the first time, 423 | * it should be either created using LZ4_createStream() or 424 | * initialized using LZ4_resetStream(). 425 | * 426 | * Note: 427 | * Using this in advance of a non-streaming-compression function is redundant, 428 | * since they all perform their own custom reset internally. 429 | * 430 | * Differences from LZ4_resetStream(): 431 | * When an LZ4_stream_t is known to be in an internally coherent state, 432 | * it will be prepared for a new compression with almost no work. 433 | * Otherwise, it will fall back to the full, expensive reset. 434 | * 435 | * LZ4_streams are guaranteed to be in a valid state when: 436 | * - returned from LZ4_createStream() 437 | * - reset by LZ4_resetStream() 438 | * - memset(stream, 0, sizeof(LZ4_stream_t)), though this is discouraged 439 | * - the stream was in a valid state and was reset by LZ4_resetStream_fast() 440 | * - the stream was in a valid state and was then used in any compression call 441 | * that returned success 442 | * - the stream was in an indeterminate state and was used in a compression 443 | * call that fully reset the state (e.g., LZ4_compress_fast_extState()) and 444 | * that returned success 445 | * 446 | * Note: 447 | * A stream that was used in a compression call that did not return success 448 | * (e.g., LZ4_compress_fast_continue()), can still be passed to this function, 449 | * however, it's history is not preserved because of previous compression 450 | * failure. 451 | */ 452 | LZ4LIB_STATIC_API void LZ4_resetStream_fast (LZ4_stream_t* streamPtr); 453 | 454 | /*! LZ4_compress_fast_extState_fastReset() : 455 | * A variant of LZ4_compress_fast_extState(). 456 | * 457 | * Using this variant avoids an expensive initialization step. 458 | * It is only safe to call if the state buffer is known to be correctly initialized already 459 | * (see above comment on LZ4_resetStream_fast() for a definition of "correctly initialized"). 460 | * From a high level, the difference is that 461 | * this function initializes the provided state with a call to something like LZ4_resetStream_fast() 462 | * while LZ4_compress_fast_extState() starts with a call to LZ4_resetStream(). 463 | */ 464 | LZ4LIB_STATIC_API int LZ4_compress_fast_extState_fastReset (void* state, const char* src, char* dst, int srcSize, int dstCapacity, int acceleration); 465 | 466 | /*! LZ4_attach_dictionary() : 467 | * This is an experimental API that allows 468 | * efficient use of a static dictionary many times. 469 | * 470 | * Rather than re-loading the dictionary buffer into a working context before 471 | * each compression, or copying a pre-loaded dictionary's LZ4_stream_t into a 472 | * working LZ4_stream_t, this function introduces a no-copy setup mechanism, 473 | * in which the working stream references the dictionary stream in-place. 474 | * 475 | * Several assumptions are made about the state of the dictionary stream. 476 | * Currently, only streams which have been prepared by LZ4_loadDict() should 477 | * be expected to work. 478 | * 479 | * Alternatively, the provided dictionaryStream may be NULL, 480 | * in which case any existing dictionary stream is unset. 481 | * 482 | * If a dictionary is provided, it replaces any pre-existing stream history. 483 | * The dictionary contents are the only history that can be referenced and 484 | * logically immediately precede the data compressed in the first subsequent 485 | * compression call. 486 | * 487 | * The dictionary will only remain attached to the working stream through the 488 | * first compression call, at the end of which it is cleared. The dictionary 489 | * stream (and source buffer) must remain in-place / accessible / unchanged 490 | * through the completion of the first compression call on the stream. 491 | */ 492 | LZ4LIB_STATIC_API void LZ4_attach_dictionary(LZ4_stream_t* workingStream, const LZ4_stream_t* dictionaryStream); 493 | 494 | #endif 495 | 496 | 497 | /*-************************************************************ 498 | * PRIVATE DEFINITIONS 499 | ************************************************************** 500 | * Do not use these definitions directly. 501 | * They are only exposed to allow static allocation of `LZ4_stream_t` and `LZ4_streamDecode_t`. 502 | * Accessing members will expose code to API and/or ABI break in future versions of the library. 503 | **************************************************************/ 504 | #define LZ4_HASHLOG (LZ4_MEMORY_USAGE-2) 505 | #define LZ4_HASHTABLESIZE (1 << LZ4_MEMORY_USAGE) 506 | #define LZ4_HASH_SIZE_U32 (1 << LZ4_HASHLOG) /* required as macro for static allocation */ 507 | 508 | #if defined(__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) 509 | #include 510 | 511 | typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; 512 | struct LZ4_stream_t_internal { 513 | uint32_t hashTable[LZ4_HASH_SIZE_U32]; 514 | uint32_t currentOffset; 515 | uint16_t dirty; 516 | uint16_t tableType; 517 | const uint8_t* dictionary; 518 | const LZ4_stream_t_internal* dictCtx; 519 | uint32_t dictSize; 520 | }; 521 | 522 | typedef struct { 523 | const uint8_t* externalDict; 524 | size_t extDictSize; 525 | const uint8_t* prefixEnd; 526 | size_t prefixSize; 527 | } LZ4_streamDecode_t_internal; 528 | 529 | #else 530 | 531 | typedef struct LZ4_stream_t_internal LZ4_stream_t_internal; 532 | struct LZ4_stream_t_internal { 533 | unsigned int hashTable[LZ4_HASH_SIZE_U32]; 534 | unsigned int currentOffset; 535 | unsigned short dirty; 536 | unsigned short tableType; 537 | const unsigned char* dictionary; 538 | const LZ4_stream_t_internal* dictCtx; 539 | unsigned int dictSize; 540 | }; 541 | 542 | typedef struct { 543 | const unsigned char* externalDict; 544 | const unsigned char* prefixEnd; 545 | size_t extDictSize; 546 | size_t prefixSize; 547 | } LZ4_streamDecode_t_internal; 548 | 549 | #endif 550 | 551 | /*! LZ4_stream_t : 552 | * information structure to track an LZ4 stream. 553 | * init this structure with LZ4_resetStream() before first use. 554 | * note : only use in association with static linking ! 555 | * this definition is not API/ABI safe, 556 | * it may change in a future version ! 557 | */ 558 | #define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4 + ((sizeof(void*)==16) ? 4 : 0) /*AS-400*/ ) 559 | #define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(unsigned long long)) 560 | union LZ4_stream_u { 561 | unsigned long long table[LZ4_STREAMSIZE_U64]; 562 | LZ4_stream_t_internal internal_donotuse; 563 | } ; /* previously typedef'd to LZ4_stream_t */ 564 | 565 | 566 | /*! LZ4_streamDecode_t : 567 | * information structure to track an LZ4 stream during decompression. 568 | * init this structure using LZ4_setStreamDecode() before first use. 569 | * note : only use in association with static linking ! 570 | * this definition is not API/ABI safe, 571 | * and may change in a future version ! 572 | */ 573 | #define LZ4_STREAMDECODESIZE_U64 (4 + ((sizeof(void*)==16) ? 2 : 0) /*AS-400*/ ) 574 | #define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long)) 575 | union LZ4_streamDecode_u { 576 | unsigned long long table[LZ4_STREAMDECODESIZE_U64]; 577 | LZ4_streamDecode_t_internal internal_donotuse; 578 | } ; /* previously typedef'd to LZ4_streamDecode_t */ 579 | 580 | 581 | /*-************************************ 582 | * Obsolete Functions 583 | **************************************/ 584 | 585 | /*! Deprecation warnings 586 | * Should deprecation warnings be a problem, 587 | * it is generally possible to disable them, 588 | * typically with -Wno-deprecated-declarations for gcc 589 | * or _CRT_SECURE_NO_WARNINGS in Visual. 590 | * Otherwise, it's also possible to define LZ4_DISABLE_DEPRECATE_WARNINGS */ 591 | #ifdef LZ4_DISABLE_DEPRECATE_WARNINGS 592 | # define LZ4_DEPRECATED(message) /* disable deprecation warnings */ 593 | #else 594 | # define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 595 | # if defined (__cplusplus) && (__cplusplus >= 201402) /* C++14 or greater */ 596 | # define LZ4_DEPRECATED(message) [[deprecated(message)]] 597 | # elif (LZ4_GCC_VERSION >= 405) || defined(__clang__) 598 | # define LZ4_DEPRECATED(message) __attribute__((deprecated(message))) 599 | # elif (LZ4_GCC_VERSION >= 301) 600 | # define LZ4_DEPRECATED(message) __attribute__((deprecated)) 601 | # elif defined(_MSC_VER) 602 | # define LZ4_DEPRECATED(message) __declspec(deprecated(message)) 603 | # else 604 | # pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler") 605 | # define LZ4_DEPRECATED(message) 606 | # endif 607 | #endif /* LZ4_DISABLE_DEPRECATE_WARNINGS */ 608 | 609 | /* Obsolete compression functions */ 610 | LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress (const char* source, char* dest, int sourceSize); 611 | LZ4_DEPRECATED("use LZ4_compress_default() instead") LZ4LIB_API int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize); 612 | LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize); 613 | LZ4_DEPRECATED("use LZ4_compress_fast_extState() instead") LZ4LIB_API int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize); 614 | LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize); 615 | LZ4_DEPRECATED("use LZ4_compress_fast_continue() instead") LZ4LIB_API int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize); 616 | 617 | /* Obsolete decompression functions */ 618 | LZ4_DEPRECATED("use LZ4_decompress_fast() instead") LZ4LIB_API int LZ4_uncompress (const char* source, char* dest, int outputSize); 619 | LZ4_DEPRECATED("use LZ4_decompress_safe() instead") LZ4LIB_API int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); 620 | 621 | /* Obsolete streaming functions; degraded functionality; do not use! 622 | * 623 | * In order to perform streaming compression, these functions depended on data 624 | * that is no longer tracked in the state. They have been preserved as well as 625 | * possible: using them will still produce a correct output. However, they don't 626 | * actually retain any history between compression calls. The compression ratio 627 | * achieved will therefore be no better than compressing each chunk 628 | * independently. 629 | */ 630 | LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API void* LZ4_create (char* inputBuffer); 631 | LZ4_DEPRECATED("Use LZ4_createStream() instead") LZ4LIB_API int LZ4_sizeofStreamState(void); 632 | LZ4_DEPRECATED("Use LZ4_resetStream() instead") LZ4LIB_API int LZ4_resetStreamState(void* state, char* inputBuffer); 633 | LZ4_DEPRECATED("Use LZ4_saveDict() instead") LZ4LIB_API char* LZ4_slideInputBuffer (void* state); 634 | 635 | /* Obsolete streaming decoding functions */ 636 | LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") LZ4LIB_API int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize); 637 | LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") LZ4LIB_API int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize); 638 | 639 | #endif /* LZ4_H_2983827168210 */ 640 | 641 | 642 | #if defined (__cplusplus) 643 | } 644 | #endif 645 | --------------------------------------------------------------------------------