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 decoded_buffer = (uint8_t*) SvPV(buffer, decoded_size);
108 encoded_size = BrotliEncoderMaxCompressedSize(decoded_size);
110 croak("Compressed size overflow");
112 Newx(encoded_buffer, encoded_size+1, uint8_t);
113 result = BrotliEncoderCompress( quality,
121 croak("Error in BrotliEncoderCompress");
123 encoded_buffer[encoded_size]=0;
125 sv_usepvn_flags(RETVAL, encoded_buffer, encoded_size, SV_SMAGIC | SV_HAS_TRAILING_NUL);
129 SV* BrotliEncoderCreateInstance()
131 RETVAL = newSViv((IV)BrotliEncoderCreateInstance(NULL, NULL, NULL));
135 SV* BrotliEncoderSetWindow(state, window)
139 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_LGWIN, window) )
146 SV* BrotliEncoderSetQuality(state, quality)
150 if( quality < BROTLI_MIN_QUALITY || quality > BROTLI_MAX_QUALITY ) {
151 croak("Invalid quality value");
153 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_QUALITY, quality) )
160 SV* BrotliEncoderSetMode(state, mode)
164 if( BrotliEncoderSetParameter((BrotliEncoderState*) SvIV(state), BROTLI_PARAM_MODE, mode) )
171 SV* BrotliEncoderCompressStream(state, in, op)
176 uint8_t *next_in, *next_out, *buffer;
177 size_t available_in, available_out;
180 next_in = (uint8_t*) SvPV(in, available_in);
181 Newx(buffer, BUFFER_SIZE, uint8_t);
182 RETVAL = newSVpv("", 0);
185 available_out = BUFFER_SIZE;
186 result = BrotliEncoderCompressStream( (BrotliEncoderState*) SvIV(state),
187 (BrotliEncoderOperation) op,
189 (const uint8_t**) &next_in,
195 croak("Error in BrotliEncoderCompressStream");
198 if( available_out != BUFFER_SIZE ) {
199 sv_catpvn(RETVAL, (const char*)buffer, BUFFER_SIZE-available_out);
203 BrotliEncoderIsFinished((BrotliEncoderState*) SvIV(state)) ||
204 (!available_in && !BrotliEncoderHasMoreOutput((BrotliEncoderState*) SvIV(state)))
211 void BrotliEncoderDestroyInstance(state)
214 BrotliEncoderDestroyInstance((BrotliEncoderState*)SvIV(state));
216 void BrotliEncoderSetCustomDictionary(state, dict)
223 data = SvPV(dict, size);
224 BrotliEncoderSetCustomDictionary((BrotliEncoderState*) SvIV(state), size, data);