static BROTLI_BOOL CompressFile(Context* context, BrotliEncoderState* s) { BROTLI_BOOL is_eof = BROTLI_FALSE; InitializeBuffers(context); for (;;) { if (context->available_in == 0 && !is_eof) { if (!ProvideInput(context)) return BROTLI_FALSE; is_eof = !HasMoreInput(context); } if (!BrotliEncoderCompressStream(s, is_eof ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS, &context->available_in, &context->next_in, &context->available_out, &context->next_out, NULL)) { /* Should detect OOM? */ fprintf(stderr, "failed to compress data [%s]\n", PrintablePath(context->current_input_path)); return BROTLI_FALSE; } if (context->available_out == 0) { if (!ProvideOutput(context)) return BROTLI_FALSE; } if (BrotliEncoderIsFinished(s)) { return FlushOutput(context); } } }
void HttpHandler::BrotliFlush() { do { this->brotli_available_in = 0; if (!BrotliEncoderCompressStream(this->brotli, BROTLI_OPERATION_FINISH, &this->brotli_available_in, &this->brotli_next_in, &this->brotli_available_out, &this->brotli_next_out, NULL)) { std::cerr << "failed to compress data" << std::endl; return; } this->response.write(reinterpret_cast<const char*>(this->brotli_out), COMPRESSION_BUFFER_SIZE - this->brotli_available_out); this->brotli_available_out = COMPRESSION_BUFFER_SIZE; this->brotli_next_out = this->brotli_out; } while(BrotliEncoderHasMoreOutput(this->brotli)); }
static SquashStatus squash_brotli_process_stream (SquashStream* stream, SquashOperation operation) { SquashBrotliStream* s = (SquashBrotliStream*) stream; if (stream->stream_type == SQUASH_STREAM_COMPRESS) { const int be_ret = BrotliEncoderCompressStream(s->ctx.encoder, squash_brotli_encoder_operation_from_squash_operation(operation), &(stream->avail_in), &(stream->next_in), &(stream->avail_out), &(stream->next_out), NULL); if (SQUASH_UNLIKELY(be_ret != 1)) return squash_error (SQUASH_FAILED); else if (stream->avail_in != 0 || BrotliEncoderHasMoreOutput(s->ctx.encoder)) return SQUASH_PROCESSING; else return SQUASH_OK; } else if (stream->stream_type == SQUASH_STREAM_DECOMPRESS) { const BrotliResult bd_ret = BrotliDecompressStream(&(stream->avail_in), &(stream->next_in), &(stream->avail_out), &(stream->next_out), NULL, s->ctx.decoder); switch (bd_ret) { case BROTLI_RESULT_SUCCESS: return SQUASH_OK; case BROTLI_RESULT_NEEDS_MORE_INPUT: return SQUASH_OK; case BROTLI_RESULT_NEEDS_MORE_OUTPUT: return SQUASH_PROCESSING; case BROTLI_RESULT_ERROR: return SQUASH_FAILED; } if (SQUASH_UNLIKELY(bd_ret != BROTLI_RESULT_SUCCESS)) return squash_error (SQUASH_FAILED); } else { squash_assert_unreachable (); } squash_assert_unreachable (); }
void HttpHandler::BrotliProcess() { this->brotli_available_in = this->buffer_stream->str().length(); this->buffer_stream->str().copy(reinterpret_cast<char*>(this->brotli_in), this->brotli_available_in, 0); this->brotli_next_in = this->brotli_in; if (!BrotliEncoderCompressStream(this->brotli, BROTLI_OPERATION_PROCESS, &this->brotli_available_in, &this->brotli_next_in, &this->brotli_available_out, &this->brotli_next_out, NULL)) { std::cerr << "failed to compress data" << std::endl; return; } if (this->brotli_available_out != COMPRESSION_BUFFER_SIZE) { this->response.write(reinterpret_cast<const char*>(this->brotli_out), COMPRESSION_BUFFER_SIZE - this->brotli_available_out); this->brotli_available_out = COMPRESSION_BUFFER_SIZE; this->brotli_next_out = this->brotli_out; } this->buffer_stream->str(""); }
static ngx_int_t ngx_http_brotli_filter_compress(ngx_http_request_t *r, ngx_http_brotli_ctx_t *ctx) { BROTLI_BOOL rc; ngx_buf_t *b; ngx_chain_t *cl; rc = BrotliEncoderCompressStream(ctx->bro, ctx->flush, &ctx->available_in, (const uint8_t **)&ctx->next_in, &ctx->available_out, &ctx->next_out, NULL); if (rc != BROTLI_TRUE) { ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, "compress() failed: %d, %d", ctx->flush, rc); return NGX_ERROR; } if (ctx->next_in) { ctx->in_buf->pos = ctx->next_in; if (ctx->available_in == 0) { ctx->next_in = NULL; } } ctx->out_buf->last = ctx->next_out; if (ctx->available_out == 0) { /* brotli wants to output some more compressed data */ cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } cl->buf = ctx->out_buf; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; ctx->redo = 1; return NGX_AGAIN; } ctx->redo = 0; if (ctx->flush == BROTLI_OPERATION_FLUSH) { ctx->flush = BROTLI_OPERATION_PROCESS; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_ERROR; } b = ctx->out_buf; if (ngx_buf_size(b) == 0) { b = ngx_calloc_buf(ctx->request->pool); if (b == NULL) { return NGX_ERROR; } } else { ctx->available_out = 0; } b->flush = 1; cl->buf = b; cl->next = NULL; *ctx->last_out = cl; ctx->last_out = &cl->next; r->connection->buffered &= ~NGX_HTTP_GZIP_BUFFERED; return NGX_OK; } if (BrotliEncoderIsFinished(ctx->bro)) { if (ngx_http_brotli_filter_end(r, ctx) != NGX_OK) { return NGX_ERROR; } return NGX_OK; } return NGX_AGAIN; }
static int Compress(int quality, int lgwin, FILE* fin, FILE* fout, const char *dictionary_path) { BrotliEncoderState* s = BrotliEncoderCreateInstance(0, 0, 0); uint8_t* buffer = (uint8_t*)malloc(kFileBufferSize << 1); uint8_t* input = buffer; uint8_t* output = buffer + kFileBufferSize; size_t available_in = 0; const uint8_t* next_in = NULL; size_t available_out = kFileBufferSize; uint8_t* next_out = output; int is_eof = 0; int is_ok = 1; if (!s || !buffer) { is_ok = 0; goto finish; } BrotliEncoderSetParameter(s, BROTLI_PARAM_QUALITY, (uint32_t)quality); BrotliEncoderSetParameter(s, BROTLI_PARAM_LGWIN, (uint32_t)lgwin); if (dictionary_path != NULL) { size_t dictionary_size = 0; uint8_t* dictionary = ReadDictionary(dictionary_path, &dictionary_size); BrotliEncoderSetCustomDictionary(s, dictionary_size, dictionary); free(dictionary); } while (1) { if (available_in == 0 && !is_eof) { available_in = fread(input, 1, kFileBufferSize, fin); next_in = input; if (ferror(fin)) break; is_eof = feof(fin); } if (!BrotliEncoderCompressStream(s, is_eof ? BROTLI_OPERATION_FINISH : BROTLI_OPERATION_PROCESS, &available_in, &next_in, &available_out, &next_out, NULL)) { is_ok = 0; break; } if (available_out != kFileBufferSize) { size_t out_size = kFileBufferSize - available_out; fwrite(output, 1, out_size, fout); if (ferror(fout)) break; available_out = kFileBufferSize; next_out = output; } if (BrotliEncoderIsFinished(s)) break; } finish: free(buffer); BrotliEncoderDestroyInstance(s); if (!is_ok) { /* Should detect OOM? */ fprintf(stderr, "failed to compress data\n"); return 0; } else if (ferror(fout)) { fprintf(stderr, "failed to write output\n"); return 0; } else if (ferror(fin)) { fprintf(stderr, "failed to read input\n"); return 0; } return 1; }