lmtbasexxlib.c /size: 5321 b    last modification: 2024-01-16 10:22
1/*
2    See license.txt in the root of this project.
3*/
4
5# include "luametatex.h"
6
7/* # define BASEXX_PDF 1 */
8
9# include <utiliof.h>
10# include <utilbasexx.h>
11# include <utillzw.h>
12
13/*tex
14
15    First I had a mix of own code and LHF code (base64 and base85) but in the end I decided to reuse
16    some of pplibs code. Performance is ok, although we can speed up the base16 coders. When needed,
17    we can have a few more but normally pure \LUA\ is quite ok for our purpose.
18
19*/
20
21# define encode_nl(L) \
22    (lua_type(L, 2) == LUA_TNUMBER) ? (lmt_tointeger(L, 2)) : ( (lua_isboolean(L, 2)) ? 80 : 0 )
23
24# define lua_iof_push(L,out) \
25    lua_pushlstring(L,(const char *) out->buf, iof_size(out))
26
27static int basexxlib_encode_16(lua_State *L)
28{
29    size_t l;
30    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
31    size_t n = 2 * l;
32    size_t nl = encode_nl(L);
33    iof *inp = iof_filter_string_reader(s, l);
34    iof *out = iof_filter_buffer_writer(n);
35    if (nl) {
36        base16_encode_ln(inp, out, 0, nl);
37    } else {
38        base16_encode(inp, out);
39    }
40    lua_iof_push(L, out);
41    iof_close(out);
42    return 1;
43}
44
45static int basexxlib_decode_16(lua_State *L)
46{
47    size_t l;
48    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
49    size_t n = l / 2;
50    iof *inp = iof_filter_string_reader(s, l);
51    iof *out = iof_filter_buffer_writer(n);
52    base16_decode(inp, out);
53    lua_iof_push(L, out);
54    iof_close(out);
55    return 1;
56}
57
58static int basexxlib_encode_64(lua_State *L)
59{
60    size_t l;
61    const unsigned char *s = (const unsigned char*) luaL_checklstring(L,1,&l);
62    size_t n = 4 * l;
63    size_t nl = encode_nl(L);
64    iof *inp = iof_filter_string_reader(s,l);
65    iof *out = iof_filter_buffer_writer(n);
66    if (nl) {
67        base64_encode_ln(inp,out,0,nl);
68    } else {
69        base64_encode(inp,out);
70    }
71    lua_iof_push(L,out);
72    iof_close(out);
73    return 1;
74}
75
76static int basexxlib_decode_64(lua_State *L)
77{
78    size_t l;
79    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
80    size_t n = l;
81    iof *inp = iof_filter_string_reader(s, l);
82    iof *out = iof_filter_buffer_writer(n);
83    base64_decode(inp, out);
84    lua_iof_push(L, out);
85    iof_close(out);
86    return 1;
87}
88
89static int basexxlib_encode_85(lua_State *L)
90{
91    size_t l;
92    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
93    size_t n = 5 * l;
94    size_t nl = encode_nl(L);
95    iof *inp = iof_filter_string_reader(s, l);
96    iof *out = iof_filter_buffer_writer(n);
97    if (nl) {
98        base85_encode_ln(inp, out, 0, 80);
99    } else {
100        base85_encode(inp, out);
101    }
102    lua_iof_push(L,out);
103    iof_close(out);
104    return 1;
105}
106
107static int basexxlib_decode_85(lua_State *L)
108{
109    size_t l;
110    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
111    size_t n = l;
112    iof *inp = iof_filter_string_reader(s, l);
113    iof *out = iof_filter_buffer_writer(n);
114    base85_decode(inp, out);
115    lua_iof_push(L, out);
116    iof_close(out);
117    return 1;
118}
119
120static int basexxlib_encode_RL(lua_State *L)
121{
122    size_t l;
123    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
124    size_t n = 2 * l;
125    iof *inp = iof_filter_string_reader(s, l);
126    iof *out = iof_filter_buffer_writer(n);
127    runlength_encode(inp, out);
128    lua_iof_push(L, out);
129    iof_close(out);
130    return 1;
131}
132
133static int basexxlib_decode_RL(lua_State *L)
134{
135    size_t l;
136    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
137    size_t n = 2 * l;
138    iof *inp = iof_filter_string_reader(s, l);
139    iof *out = iof_filter_buffer_writer(n);
140    runlength_decode(inp, out);
141    lua_iof_push(L, out);
142    iof_close(out);
143    return 1;
144}
145
146static int basexxlib_encode_LZW(lua_State *L)
147{
148    size_t l;
149    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
150    size_t n = 2 * l;
151    char *t = lmt_memory_malloc(n);
152    int flags = lmt_optinteger(L, 2, LZW_ENCODER_DEFAULTS);
153    iof *inp = iof_filter_string_reader(s, l);
154    iof *out = iof_filter_string_writer(t, n);
155    lzw_encode(inp, out, flags);
156    lua_pushlstring(L, t, iof_size(out));
157    lmt_memory_free(t);
158    return 1;
159}
160
161static int basexxlib_decode_LZW(lua_State *L)
162{
163    size_t l;
164    const unsigned char *s = (const unsigned char*) luaL_checklstring(L, 1, &l);
165    size_t n = 2 * l;
166    iof *inp = iof_filter_string_reader(s, l);
167    iof *out = iof_filter_buffer_writer(n);
168    int flags = lmt_optinteger(L, 2, LZW_DECODER_DEFAULTS);
169    lzw_decode(inp, out, flags);
170    lua_iof_push(L, out);
171    iof_close(out);
172    return 1;
173}
174
175static struct luaL_Reg basexxlib_function_list[] = {
176    { "encode16",  basexxlib_encode_16  },
177    { "decode16",  basexxlib_decode_16  },
178    { "encode64",  basexxlib_encode_64  },
179    { "decode64",  basexxlib_decode_64  },
180    { "encode85",  basexxlib_encode_85  },
181    { "decode85",  basexxlib_decode_85  },
182    { "encodeRL",  basexxlib_encode_RL  },
183    { "decodeRL",  basexxlib_decode_RL  },
184    { "encodeLZW", basexxlib_encode_LZW },
185    { "decodeLZW", basexxlib_decode_LZW },
186    { NULL,        NULL                 },
187};
188
189int luaopen_basexx(lua_State *L) {
190    lua_newtable(L);
191    luaL_setfuncs(L, basexxlib_function_list, 0);
192    return 1;
193}
194