1 #define PERL_NO_GET_CONTEXT
8 #include <dec/decode.h>
9 #include <enc/encode.h>
10 #include <common/dictionary.h>
12 #define BUFFER_SIZE 1048576
14 MODULE = IO::Compress::Brotli PACKAGE = IO::Uncompress::Brotli
22 uint8_t *encoded_buffer, *decoded_buffer;
24 encoded_buffer = (uint8_t*) SvPV(buffer, encoded_size);
25 if(!BrotliDecompressedSize(encoded_size, encoded_buffer, &decoded_size)){
26 croak("Error in BrotliDecompressedSize");
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");
34 sv_usepvn_flags(RETVAL, decoded_buffer, decoded_size, SV_HAS_TRAILING_NUL);
38 SV* BrotliDecoderCreateInstance()
40 RETVAL = newSViv((IV)BrotliDecoderCreateInstance(NULL, NULL, NULL));
44 void BrotliDecoderDestroyInstance(state)
47 BrotliDecoderDestroyInstance((BrotliDecoderState*)SvIV(state));
49 SV* BrotliDecoderDecompressStream(state, in)
53 uint8_t *next_in, *next_out, *buffer;
54 size_t available_in, available_out;
55 BrotliDecoderResult result;
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) {
63 available_out=BUFFER_SIZE;
64 result = BrotliDecoderDecompressStream( (BrotliDecoderState*) SvIV(state),
66 (const uint8_t**) &next_in,
72 croak("Error in BrotliDecoderDecompressStream");
74 sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out);
80 void BrotliDecoderSetCustomDictionary(state, dict)
87 data = SvPV(dict, size);
88 BrotliDecoderSetCustomDictionary((BrotliDecoderState*) SvIV(state), size, data);
91 MODULE = IO::Compress::Brotli PACKAGE = IO::Compress::Brotli
94 SV* bro(buffer, quality=BROTLI_DEFAULT_QUALITY, lgwin=BROTLI_DEFAULT_WINDOW)
101 uint8_t *encoded_buffer, *decoded_buffer;
104 if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) {
105 croak("Invalid quality value");
107 if( lgwin < kBrotliMinWindowBits || lgwin > kBrotliMaxWindowBits ) {
108 croak("Invalid window value");
110 decoded_buffer = (uint8_t*) SvPV(buffer, decoded_size);
111 encoded_size = BrotliEncoderMaxCompressedSize(decoded_size);
113 croak("Compressed size overflow");
115 Newx(encoded_buffer, encoded_size+1, uint8_t);
116 result = BrotliEncoderCompress( quality,
125 croak("Error in BrotliEncoderCompress");
127 encoded_buffer[encoded_size]=0;
129 sv_usepvn_flags(RETVAL, encoded_buffer, encoded_size, SV_SMAGIC | SV_HAS_TRAILING_NUL);
133 SV* BrotliEncoderCreateInstance()
135 RETVAL = newSViv((IV)BrotliEncoderCreateInstance(NULL, NULL, NULL));
139 SV* BrotliEncoderSetWindow(state, window)
143 if( window < kBrotliMinWindowBits || window > kBrotliMaxWindowBits ) {
144 croak("Invalid window value");
146 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_LGWIN, window) )
153 SV* BrotliEncoderSetQuality(state, quality)
157 if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) {
158 croak("Invalid quality value");
160 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_QUALITY, quality) )
167 SV* BrotliEncoderSetMode(state, mode)
171 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_MODE, mode) )
178 SV* BrotliEncoderCompressStream(state, in, op)
183 uint8_t *next_in, *next_out, *buffer;
184 size_t available_in, available_out;
187 next_in = (uint8_t*) SvPV(in, available_in);
188 Newx(buffer, BUFFER_SIZE, uint8_t);
189 RETVAL = newSVpv("", 0);
192 available_out = BUFFER_SIZE;
193 result = BrotliEncoderCompressStream( (BrotliEncoderState*) SvIV(state),
194 (BrotliEncoderOperation) op,
196 (const uint8_t**) &next_in,
202 croak("Error in BrotliEncoderCompressStream");
205 if( available_out != BUFFER_SIZE ) {
206 sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out);
210 BrotliEncoderIsFinished((BrotliEncoderState*) SvIV(state)) ||
211 (!available_in && !BrotliEncoderHasMoreOutput((BrotliEncoderState*) SvIV(state)))
218 void BrotliEncoderDestroyInstance(state)
221 BrotliEncoderDestroyInstance((BrotliEncoderState*)SvIV(state));
223 void BrotliEncoderSetCustomDictionary(state, dict)
230 data = SvPV(dict, size);
231 BrotliEncoderSetCustomDictionary((BrotliEncoderState*) SvIV(state), size, data);