1+ /*
2+ * This file is a part of: https://github.com/brilliantlabsAR/frame-codebase
3+ *
4+ * Authored by: Raj Nakarja / Brilliant Labs Ltd. (raj@brilliant.xyz)
5+ * Rohit Rathnam / Silicon Witchery AB (rohit@siliconwitchery.com)
6+ * Uma S. Gupta / Techno Exponent (umasankar@technoexponent.com)
7+ *
8+ * ISC Licence
9+ *
10+ * Copyright © 2025 Brilliant Labs Ltd.
11+ *
12+ * Permission to use, copy, modify, and/or distribute this software for any
13+ * purpose with or without fee is hereby granted, provided that the above
14+ * copyright notice and this permission notice appear in all copies.
15+ *
16+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
17+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
18+ * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
19+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
20+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
21+ * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
22+ * PERFORMANCE OF THIS SOFTWARE.
23+ */
24+
25+ #include <string.h>
26+ #include "compression.h"
27+ #include "frame_lua_libraries.h"
28+ #include "lauxlib.h"
29+ #include "lua.h"
30+ #include "watchdog.h"
31+
32+ static int registered_function = 0 ;
33+ static uint8_t decompression_buffer [4096 ];
34+ static size_t decompression_buffer_size = 0 ;
35+
36+ static void decompression_lua_handler (lua_State * L , lua_Debug * ar )
37+ {
38+ sethook_watchdog (L );
39+
40+ if (registered_function != 0 )
41+ {
42+ lua_rawgeti (L , LUA_REGISTRYINDEX , registered_function );
43+
44+ lua_pushlstring (L ,
45+ (char * )decompression_buffer ,
46+ decompression_buffer_size );
47+
48+ if (lua_pcall (L , 1 , 0 , 0 ) != LUA_OK )
49+ {
50+ luaL_error (L , "%s" , lua_tostring (L , -1 ));
51+ }
52+ }
53+ }
54+
55+ static void process_function_callback (void * context ,
56+ void * data ,
57+ size_t data_size )
58+ {
59+ decompression_buffer_size = data_size ;
60+ memcpy (decompression_buffer , data , data_size );
61+
62+ lua_sethook (L_global ,
63+ decompression_lua_handler ,
64+ LUA_MASKCALL | LUA_MASKRET | LUA_MASKLINE | LUA_MASKCOUNT ,
65+ 1 );
66+ }
67+
68+ static int lua_compression_register_process_function (lua_State * L )
69+ {
70+ if (lua_isnil (L , 1 ))
71+ {
72+ registered_function = 0 ;
73+ return 0 ;
74+ }
75+
76+ if (lua_isfunction (L , 1 ))
77+ {
78+ registered_function = luaL_ref (L , LUA_REGISTRYINDEX );
79+ return 0 ;
80+ }
81+
82+ luaL_error (L , "expected nil or function" );
83+
84+ return 0 ;
85+ }
86+
87+ static int lua_compression_decompress (lua_State * L )
88+ {
89+ size_t length ;
90+ const char * data = luaL_checklstring (L , 1 , & length );
91+
92+ lua_Integer block_size = luaL_checkinteger (L , 2 );
93+
94+ if (block_size <= 0 )
95+ {
96+ luaL_error (L , "bytes must be greater than 0" );
97+ }
98+
99+ int status = compression_decompress (block_size ,
100+ data ,
101+ length ,
102+ process_function_callback ,
103+ NULL );
104+
105+ if (status )
106+ {
107+ luaL_error (L , "decompression failed" );
108+ }
109+
110+ return 0 ;
111+ }
112+
113+ void lua_open_compression_library (lua_State * L )
114+ {
115+ lua_getglobal (L , "frame" );
116+
117+ lua_newtable (L );
118+
119+ lua_pushcfunction (L , lua_compression_register_process_function );
120+ lua_setfield (L , -2 , "process_function" );
121+
122+ lua_pushcfunction (L , lua_compression_decompress );
123+ lua_setfield (L , -2 , "decompress" );
124+
125+ lua_setfield (L , -2 , "compression" );
126+
127+ lua_pop (L , 1 );
128+ }
0 commit comments