Skip to content

Commit 1165b4c

Browse files
mtheallfincs
authored andcommitted
Add decompression routines
1 parent caacf37 commit 1165b4c

4 files changed

Lines changed: 1040 additions & 0 deletions

File tree

libctru/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ SOURCES := source \
3131
source/services \
3232
source/services/soc \
3333
source/applets \
34+
source/util/decompress \
3435
source/util/rbtree \
3536
source/util/utf \
3637
source/system

libctru/include/3ds.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern "C" {
2222
#include <3ds/gfx.h>
2323
#include <3ds/console.h>
2424
#include <3ds/env.h>
25+
#include <3ds/util/decompress.h>
2526
#include <3ds/util/utf.h>
2627

2728
#include <3ds/allocator/linear.h>
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/**
2+
* @file decompress.h
3+
* @brief Decompression functions.
4+
*/
5+
#pragma once
6+
7+
#include <stdbool.h>
8+
#include <sys/types.h>
9+
10+
/** @brief I/O vector */
11+
typedef struct
12+
{
13+
void *data; ///< I/O buffer
14+
size_t size; ///< Buffer size
15+
} decompressIOVec;
16+
17+
/** @brief Data callback */
18+
typedef ssize_t (*decompressCallback)(void *userdata, void *buffer,
19+
size_t size);
20+
21+
#ifdef __cplusplus
22+
extern "C"
23+
{
24+
#endif
25+
26+
/** @brief Decompression callback for file descriptors
27+
* @param[in] userdata Address of file descriptor
28+
* @param[in] buffer Buffer to write into
29+
* @param[in] size Size to read from file descriptor
30+
* @returns Number of bytes read
31+
*/
32+
ssize_t decompressCallback_FD(void *userdata, void *buffer, size_t size);
33+
34+
/** @brief Decompression callback for stdio FILE*
35+
* @param[in] userdata FILE*
36+
* @param[in] buffer Buffer to write into
37+
* @param[in] size Size to read from file descriptor
38+
* @returns Number of bytes read
39+
*/
40+
ssize_t decompressCallback_Stdio(void *userdata, void *buffer, size_t size);
41+
42+
/** @brief Decompress data
43+
* @param[in] iov Output vector
44+
* @param[in] iovcnt Number of buffers
45+
* @param[in] callback Data callback (see note)
46+
* @param[in] userdata User data passed to callback (see note)
47+
* @param[in] insize Size of userdata (see note)
48+
* @returns Whether succeeded
49+
*
50+
* @note If callback is null, userdata is a pointer to memory to read from,
51+
* and insize is the size of that data. If callback is not null,
52+
* userdata is passed to callback to fetch more data, and insize is
53+
* unused.
54+
*/
55+
bool decompressV(const decompressIOVec *iov, size_t iovcnt,
56+
decompressCallback callback, void *userdata, size_t insize);
57+
58+
/** @brief Decompress data
59+
* @param[in] output Output buffer
60+
* @param[in] size Output size limit
61+
* @param[in] callback Data callback (see decompressV())
62+
* @param[in] userdata User data passed to callback (see decompressV())
63+
* @param[in] insize Size of userdata (see decompressV())
64+
* @returns Whether succeeded
65+
*/
66+
static inline bool
67+
decompress(void *output, size_t size, decompressCallback callback,
68+
void *userdata, size_t insize)
69+
{
70+
decompressIOVec iov;
71+
iov.data = output;
72+
iov.size = size;
73+
74+
return decompressV(&iov, 1, callback, userdata, insize);
75+
}
76+
77+
/** @brief Decompress LZSS/LZ10
78+
* @param[in] iov Output vector
79+
* @param[in] iovcnt Number of buffers
80+
* @param[in] callback Data callback (see decompressV())
81+
* @param[in] userdata User data passed to callback (see decompressV())
82+
* @param[in] insize Size of userdata (see decompressV())
83+
* @returns Whether succeeded
84+
*/
85+
bool decompressV_LZSS(const decompressIOVec *iov, size_t iovcnt,
86+
decompressCallback callback, void *userdata,
87+
size_t insize);
88+
89+
/** @brief Decompress LZSS/LZ10
90+
* @param[in] output Output buffer
91+
* @param[in] size Output size limit
92+
* @param[in] callback Data callback (see decompressV())
93+
* @param[in] userdata User data passed to callback (see decompressV())
94+
* @param[in] insize Size of userdata (see decompressV())
95+
* @returns Whether succeeded
96+
*/
97+
static inline bool
98+
decompress_LZSS(void *output, size_t size, decompressCallback callback,
99+
void *userdata, size_t insize)
100+
{
101+
decompressIOVec iov;
102+
iov.data = output;
103+
iov.size = size;
104+
105+
return decompressV_LZSS(&iov, 1, callback, userdata, insize);
106+
}
107+
108+
/** @brief Decompress LZ11
109+
* @param[in] iov Output vector
110+
* @param[in] iovcnt Number of buffers
111+
* @param[in] callback Data callback (see decompressV())
112+
* @param[in] userdata User data passed to callback (see decompressV())
113+
* @param[in] insize Size of userdata (see decompressV())
114+
* @returns Whether succeeded
115+
*/
116+
bool decompressV_LZ11(const decompressIOVec *iov, size_t iovcnt,
117+
decompressCallback callback, void *userdata,
118+
size_t insize);
119+
120+
/** @brief Decompress LZ11
121+
* @param[in] output Output buffer
122+
* @param[in] size Output size limit
123+
* @param[in] callback Data callback (see decompressV())
124+
* @param[in] userdata User data passed to callback (see decompressV())
125+
* @param[in] insize Size of userdata (see decompressV())
126+
* @returns Whether succeeded
127+
*/
128+
static inline bool
129+
decompress_LZ11(void *output, size_t size, decompressCallback callback,
130+
void *userdata, size_t insize)
131+
{
132+
decompressIOVec iov;
133+
iov.data = output;
134+
iov.size = size;
135+
136+
return decompressV_LZ11(&iov, 1, callback, userdata, insize);
137+
}
138+
139+
/** @brief Decompress Huffman
140+
* @param[in] iov Output vector
141+
* @param[in] iovcnt Number of buffers
142+
* @param[in] callback Data callback (see decompressV())
143+
* @param[in] userdata User data passed to callback (see decompressV())
144+
* @param[in] insize Size of userdata (see decompressV())
145+
* @returns Whether succeeded
146+
*/
147+
bool decompressV_Huff(const decompressIOVec *iov, size_t iovcnt,
148+
decompressCallback callback, void *userdata,
149+
size_t insize);
150+
151+
/** @brief Decompress Huffman
152+
* @param[in] output Output buffer
153+
* @param[in] size Output size limit
154+
* @param[in] callback Data callback (see decompressV())
155+
* @param[in] userdata User data passed to callback (see decompressV())
156+
* @param[in] insize Size of userdata (see decompressV())
157+
* @returns Whether succeeded
158+
*/
159+
static inline bool
160+
decompress_Huff(void *output, size_t size, decompressCallback callback,
161+
void *userdata, size_t insize)
162+
{
163+
decompressIOVec iov;
164+
iov.data = output;
165+
iov.size = size;
166+
167+
return decompressV_Huff(&iov, 1, callback, userdata, insize);
168+
}
169+
170+
/** @brief Decompress run-length encoding
171+
* @param[in] iov Output vector
172+
* @param[in] iovcnt Number of buffers
173+
* @param[in] callback Data callback (see decompressV())
174+
* @param[in] userdata User data passed to callback (see decompressV())
175+
* @param[in] insize Size of userdata (see decompressV())
176+
* @returns Whether succeeded
177+
*/
178+
bool decompressV_RLE(const decompressIOVec *iov, size_t iovcnt,
179+
decompressCallback callback, void *userdata,
180+
size_t insize);
181+
182+
/** @brief Decompress run-length encoding
183+
* @param[in] output Output buffer
184+
* @param[in] size Output size limit
185+
* @param[in] callback Data callback (see decompressV())
186+
* @param[in] userdata User data passed to callback (see decompressV())
187+
* @param[in] insize Size of userdata (see decompressV())
188+
* @returns Whether succeeded
189+
*/
190+
static inline bool
191+
decompress_RLE(void *output, size_t size, decompressCallback callback,
192+
void *userdata, size_t insize)
193+
{
194+
decompressIOVec iov;
195+
iov.data = output;
196+
iov.size = size;
197+
198+
return decompressV_RLE(&iov, 1, callback, userdata, insize);
199+
}
200+
201+
#ifdef __cplusplus
202+
}
203+
#endif

0 commit comments

Comments
 (0)