Allow only window values between kBrotliMinWindowBits and kBrotliMaxindowBits
[io-compress-brotli.git] / Brotli.xs
1 #define PERL_NO_GET_CONTEXT
2 #include "EXTERN.h"
3 #include "perl.h"
4 #include "XSUB.h"
5
6 #include "ppport.h"
7
8 #include <dec/decode.h>
9 #include <enc/encode.h>
10 #include <common/dictionary.h>
11
12 #define BUFFER_SIZE 1048576
13
14 MODULE = IO::Compress::Brotli PACKAGE = IO::Uncompress::Brotli
15 PROTOTYPES: ENABLE
16
17 SV* unbro(buffer)
18 SV* buffer
19 PREINIT:
20 size_t decoded_size;
21 STRLEN encoded_size;
22 uint8_t *encoded_buffer, *decoded_buffer;
23 CODE:
24 encoded_buffer = (uint8_t*) SvPV(buffer, encoded_size);
25 if(!BrotliDecompressedSize(encoded_size, encoded_buffer, &decoded_size)){
26 croak("Error in BrotliDecompressedSize");
27 }
28 Newx(decoded_buffer, decoded_size+1, uint8_t);
29 decoded_buffer[decoded_size]=0;
30 if(!BrotliDecoderDecompress(encoded_size, encoded_buffer, &decoded_size, decoded_buffer)){
31 croak("Error in BrotliDecoderDecompress");
32 }
33 RETVAL = newSV(0);
34 sv_usepvn_flags(RETVAL, decoded_buffer, decoded_size, SV_HAS_TRAILING_NUL);
35 OUTPUT:
36 RETVAL
37
38 SV* BrotliDecoderCreateInstance()
39 CODE:
40 RETVAL = newSViv((IV)BrotliDecoderCreateInstance(NULL, NULL, NULL));
41 OUTPUT:
42 RETVAL
43
44 void BrotliDecoderDestroyInstance(state)
45 SV* state
46 CODE:
47 BrotliDecoderDestroyInstance((BrotliDecoderState*)SvIV(state));
48
49 SV* BrotliDecoderDecompressStream(state, in)
50 SV* state
51 SV* in
52 PREINIT:
53 uint8_t *next_in, *next_out, *buffer;
54 size_t available_in, available_out;
55 BrotliDecoderResult result;
56 CODE:
57 next_in = (uint8_t*) SvPV(in, available_in);
58 Newx(buffer, BUFFER_SIZE, uint8_t);
59 RETVAL = newSVpv("", 0);
60 result = BROTLI_RESULT_NEEDS_MORE_OUTPUT;
61 while(result == BROTLI_RESULT_NEEDS_MORE_OUTPUT) {
62 next_out = buffer;
63 available_out=BUFFER_SIZE;
64 result = BrotliDecoderDecompressStream( (BrotliDecoderState*) SvIV(state),
65 &available_in,
66 (const uint8_t**) &next_in,
67 &available_out,
68 &next_out,
69 NULL );
70 if(!result){
71 Safefree(buffer);
72 croak("Error in BrotliDecoderDecompressStream");
73 }
74 sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out);
75 }
76 Safefree(buffer);
77 OUTPUT:
78 RETVAL
79
80 void BrotliDecoderSetCustomDictionary(state, dict)
81 SV* state
82 SV* dict
83 PREINIT:
84 size_t size;
85 uint8_t *data;
86 CODE:
87 data = SvPV(dict, size);
88 BrotliDecoderSetCustomDictionary((BrotliDecoderState*) SvIV(state), size, data);
89
90
91 MODULE = IO::Compress::Brotli PACKAGE = IO::Compress::Brotli
92 PROTOTYPES: ENABLE
93
94 SV* bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW)
95 SV* buffer
96 U32 quality
97 U32 lgwin
98 PREINIT:
99 size_t encoded_size;
100 STRLEN decoded_size;
101 uint8_t *encoded_buffer, *decoded_buffer;
102 BROTLI_BOOL result;
103 CODE:
104 if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) {
105 croak("Invalid quality value");
106 }
107 if( lgwin < kBrotliMinWindowBits || lgwin > kBrotliMaxWindowBits ) {
108 croak("Invalid window value");
109 }
110 decoded_buffer = (uint8_t*) SvPV(buffer, decoded_size);
111 encoded_size = BrotliEncoderMaxCompressedSize(decoded_size);
112 if(!encoded_size){
113 croak("Compressed size overflow");
114 }
115 Newx(encoded_buffer, encoded_size+1, uint8_t);
116 result = BrotliEncoderCompress( quality,
117 lgwin,
118 BROTLI_DEFAULT_MODE,
119 decoded_size,
120 decoded_buffer,
121 &encoded_size,
122 encoded_buffer );
123 if(!result){
124 Safefree(buffer);
125 croak("Error in BrotliEncoderCompress");
126 }
127 encoded_buffer[encoded_size]=0;
128 RETVAL = newSV(0);
129 sv_usepvn_flags(RETVAL, encoded_buffer, encoded_size, SV_SMAGIC | SV_HAS_TRAILING_NUL);
130 OUTPUT:
131 RETVAL
132
133 SV* BrotliEncoderCreateInstance()
134 CODE:
135 RETVAL = newSViv((IV)BrotliEncoderCreateInstance(NULL, NULL, NULL));
136 OUTPUT:
137 RETVAL
138
139 SV* BrotliEncoderSetWindow(state, window)
140 SV* state
141 U32 window
142 CODE:
143 if( window < kBrotliMinWindowBits || window > kBrotliMaxWindowBits ) {
144 croak("Invalid window value");
145 }
146 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_LGWIN, window) )
147 RETVAL = newSVuv(1);
148 else
149 RETVAL = newSVuv(0);
150 OUTPUT:
151 RETVAL
152
153 SV* BrotliEncoderSetQuality(state, quality)
154 SV* state
155 U32 quality
156 CODE:
157 if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) {
158 croak("Invalid quality value");
159 }
160 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_QUALITY, quality) )
161 RETVAL = newSVuv(1);
162 else
163 RETVAL = newSVuv(0);
164 OUTPUT:
165 RETVAL
166
167 SV* BrotliEncoderSetMode(state, mode)
168 SV* state
169 U32 mode
170 CODE:
171 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_MODE, mode) )
172 RETVAL = newSVuv(1);
173 else
174 RETVAL = newSVuv(0);
175 OUTPUT:
176 RETVAL
177
178 SV* BrotliEncoderCompressStream(state, in, op)
179 SV* state
180 SV* in
181 U8 op
182 PREINIT:
183 uint8_t *next_in, *next_out, *buffer;
184 size_t available_in, available_out;
185 BROTLI_BOOL result;
186 CODE:
187 next_in = (uint8_t*) SvPV(in, available_in);
188 Newx(buffer, BUFFER_SIZE, uint8_t);
189 RETVAL = newSVpv("", 0);
190 while(1) {
191 next_out = buffer;
192 available_out = BUFFER_SIZE;
193 result = BrotliEncoderCompressStream( (BrotliEncoderState*) SvIV(state),
194 (BrotliEncoderOperation) op,
195 &available_in,
196 (const uint8_t**) &next_in,
197 &available_out,
198 &next_out,
199 NULL );
200 if(!result) {
201 Safefree(buffer);
202 croak("Error in BrotliEncoderCompressStream");
203 }
204
205 if( available_out != BUFFER_SIZE ) {
206 sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out);
207 }
208
209 if(
210 BrotliEncoderIsFinished((BrotliEncoderState*) SvIV(state)) ||
211 (!available_in && !BrotliEncoderHasMoreOutput((BrotliEncoderState*) SvIV(state)))
212 ) break;
213 }
214 Safefree(buffer);
215 OUTPUT:
216 RETVAL
217
218 void BrotliEncoderDestroyInstance(state)
219 SV* state
220 CODE:
221 BrotliEncoderDestroyInstance((BrotliEncoderState*)SvIV(state));
222
223 void BrotliEncoderSetCustomDictionary(state, dict)
224 SV* state
225 SV* dict
226 PREINIT:
227 size_t size;
228 uint8_t *data;
229 CODE:
230 data = SvPV(dict, size);
231 BrotliEncoderSetCustomDictionary((BrotliEncoderState*) SvIV(state), size, data);
This page took 0.028656 seconds and 5 git commands to generate.