aboutsummaryrefslogtreecommitdiffstats
path: root/app/nginx/src/http/modules/ngx_http_image_filter_module.c
diff options
context:
space:
mode:
Diffstat (limited to 'app/nginx/src/http/modules/ngx_http_image_filter_module.c')
-rw-r--r--app/nginx/src/http/modules/ngx_http_image_filter_module.c1675
1 files changed, 0 insertions, 1675 deletions
diff --git a/app/nginx/src/http/modules/ngx_http_image_filter_module.c b/app/nginx/src/http/modules/ngx_http_image_filter_module.c
deleted file mode 100644
index dbec5d8..0000000
--- a/app/nginx/src/http/modules/ngx_http_image_filter_module.c
+++ /dev/null
@@ -1,1675 +0,0 @@
-
-/*
- * Copyright (C) Igor Sysoev
- * Copyright (C) Nginx, Inc.
- */
-
-
-#include <ngx_config.h>
-#include <ngx_core.h>
-#include <ngx_http.h>
-
-#include <gd.h>
-
-
-#define NGX_HTTP_IMAGE_OFF 0
-#define NGX_HTTP_IMAGE_TEST 1
-#define NGX_HTTP_IMAGE_SIZE 2
-#define NGX_HTTP_IMAGE_RESIZE 3
-#define NGX_HTTP_IMAGE_CROP 4
-#define NGX_HTTP_IMAGE_ROTATE 5
-
-
-#define NGX_HTTP_IMAGE_START 0
-#define NGX_HTTP_IMAGE_READ 1
-#define NGX_HTTP_IMAGE_PROCESS 2
-#define NGX_HTTP_IMAGE_PASS 3
-#define NGX_HTTP_IMAGE_DONE 4
-
-
-#define NGX_HTTP_IMAGE_NONE 0
-#define NGX_HTTP_IMAGE_JPEG 1
-#define NGX_HTTP_IMAGE_GIF 2
-#define NGX_HTTP_IMAGE_PNG 3
-#define NGX_HTTP_IMAGE_WEBP 4
-
-
-#define NGX_HTTP_IMAGE_BUFFERED 0x08
-
-
-typedef struct {
- ngx_uint_t filter;
- ngx_uint_t width;
- ngx_uint_t height;
- ngx_uint_t angle;
- ngx_uint_t jpeg_quality;
- ngx_uint_t webp_quality;
- ngx_uint_t sharpen;
-
- ngx_flag_t transparency;
- ngx_flag_t interlace;
-
- ngx_http_complex_value_t *wcv;
- ngx_http_complex_value_t *hcv;
- ngx_http_complex_value_t *acv;
- ngx_http_complex_value_t *jqcv;
- ngx_http_complex_value_t *wqcv;
- ngx_http_complex_value_t *shcv;
-
- size_t buffer_size;
-} ngx_http_image_filter_conf_t;
-
-
-typedef struct {
- u_char *image;
- u_char *last;
-
- size_t length;
-
- ngx_uint_t width;
- ngx_uint_t height;
- ngx_uint_t max_width;
- ngx_uint_t max_height;
- ngx_uint_t angle;
-
- ngx_uint_t phase;
- ngx_uint_t type;
- ngx_uint_t force;
-} ngx_http_image_filter_ctx_t;
-
-
-static ngx_int_t ngx_http_image_send(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in);
-static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in);
-static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in);
-static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r);
-static ngx_buf_t *ngx_http_image_json(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static ngx_buf_t *ngx_http_image_asis(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static void ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b);
-static ngx_int_t ngx_http_image_size(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-
-static ngx_buf_t *ngx_http_image_resize(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static gdImagePtr ngx_http_image_source(ngx_http_request_t *r,
- ngx_http_image_filter_ctx_t *ctx);
-static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h,
- int colors);
-static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type,
- gdImagePtr img, int *size);
-static void ngx_http_image_cleanup(void *data);
-static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *cv, ngx_uint_t v);
-static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value);
-
-
-static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf);
-static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent,
- void *child);
-static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf,
- ngx_command_t *cmd, void *conf);
-static char *ngx_http_image_filter_webp_quality(ngx_conf_t *cf,
- ngx_command_t *cmd, void *conf);
-static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf);
-static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf);
-
-
-static ngx_command_t ngx_http_image_filter_commands[] = {
-
- { ngx_string("image_filter"),
- NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
- ngx_http_image_filter,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_jpeg_quality"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_image_filter_jpeg_quality,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_webp_quality"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_image_filter_webp_quality,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_sharpen"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_http_image_filter_sharpen,
- NGX_HTTP_LOC_CONF_OFFSET,
- 0,
- NULL },
-
- { ngx_string("image_filter_transparency"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, transparency),
- NULL },
-
- { ngx_string("image_filter_interlace"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
- ngx_conf_set_flag_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, interlace),
- NULL },
-
- { ngx_string("image_filter_buffer"),
- NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
- ngx_conf_set_size_slot,
- NGX_HTTP_LOC_CONF_OFFSET,
- offsetof(ngx_http_image_filter_conf_t, buffer_size),
- NULL },
-
- ngx_null_command
-};
-
-
-static ngx_http_module_t ngx_http_image_filter_module_ctx = {
- NULL, /* preconfiguration */
- ngx_http_image_filter_init, /* postconfiguration */
-
- NULL, /* create main configuration */
- NULL, /* init main configuration */
-
- NULL, /* create server configuration */
- NULL, /* merge server configuration */
-
- ngx_http_image_filter_create_conf, /* create location configuration */
- ngx_http_image_filter_merge_conf /* merge location configuration */
-};
-
-
-ngx_module_t ngx_http_image_filter_module = {
- NGX_MODULE_V1,
- &ngx_http_image_filter_module_ctx, /* module context */
- ngx_http_image_filter_commands, /* module directives */
- NGX_HTTP_MODULE, /* module type */
- NULL, /* init master */
- NULL, /* init module */
- NULL, /* init process */
- NULL, /* init thread */
- NULL, /* exit thread */
- NULL, /* exit process */
- NULL, /* exit master */
- NGX_MODULE_V1_PADDING
-};
-
-
-static ngx_http_output_header_filter_pt ngx_http_next_header_filter;
-static ngx_http_output_body_filter_pt ngx_http_next_body_filter;
-
-
-static ngx_str_t ngx_http_image_types[] = {
- ngx_string("image/jpeg"),
- ngx_string("image/gif"),
- ngx_string("image/png"),
- ngx_string("image/webp")
-};
-
-
-static ngx_int_t
-ngx_http_image_header_filter(ngx_http_request_t *r)
-{
- off_t len;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) {
- return ngx_http_next_header_filter(r);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx) {
- ngx_http_set_ctx(r, NULL, ngx_http_image_filter_module);
- return ngx_http_next_header_filter(r);
- }
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (conf->filter == NGX_HTTP_IMAGE_OFF) {
- return ngx_http_next_header_filter(r);
- }
-
- if (r->headers_out.content_type.len
- >= sizeof("multipart/x-mixed-replace") - 1
- && ngx_strncasecmp(r->headers_out.content_type.data,
- (u_char *) "multipart/x-mixed-replace",
- sizeof("multipart/x-mixed-replace") - 1)
- == 0)
- {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: multipart/x-mixed-replace response");
-
- return NGX_ERROR;
- }
-
- ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t));
- if (ctx == NULL) {
- return NGX_ERROR;
- }
-
- ngx_http_set_ctx(r, ctx, ngx_http_image_filter_module);
-
- len = r->headers_out.content_length_n;
-
- if (len != -1 && len > (off_t) conf->buffer_size) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: too big response: %O", len);
-
- return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE;
- }
-
- if (len == -1) {
- ctx->length = conf->buffer_size;
-
- } else {
- ctx->length = (size_t) len;
- }
-
- if (r->headers_out.refresh) {
- r->headers_out.refresh->hash = 0;
- }
-
- r->main_filter_need_in_memory = 1;
- r->allow_ranges = 0;
-
- return NGX_OK;
-}
-
-
-static ngx_int_t
-ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in)
-{
- ngx_int_t rc;
- ngx_str_t *ct;
- ngx_chain_t out;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "image filter");
-
- if (in == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx == NULL) {
- return ngx_http_next_body_filter(r, in);
- }
-
- switch (ctx->phase) {
-
- case NGX_HTTP_IMAGE_START:
-
- ctx->type = ngx_http_image_test(r, in);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (ctx->type == NGX_HTTP_IMAGE_NONE) {
-
- if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
- out.buf = ngx_http_image_json(r, NULL);
-
- if (out.buf) {
- out.next = NULL;
- ctx->phase = NGX_HTTP_IMAGE_DONE;
-
- return ngx_http_image_send(r, ctx, &out);
- }
- }
-
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- /* override content type */
-
- ct = &ngx_http_image_types[ctx->type - 1];
- r->headers_out.content_type_len = ct->len;
- r->headers_out.content_type = *ct;
- r->headers_out.content_type_lowcase = NULL;
-
- if (conf->filter == NGX_HTTP_IMAGE_TEST) {
- ctx->phase = NGX_HTTP_IMAGE_PASS;
-
- return ngx_http_image_send(r, ctx, in);
- }
-
- ctx->phase = NGX_HTTP_IMAGE_READ;
-
- /* fall through */
-
- case NGX_HTTP_IMAGE_READ:
-
- rc = ngx_http_image_read(r, in);
-
- if (rc == NGX_AGAIN) {
- return NGX_OK;
- }
-
- if (rc == NGX_ERROR) {
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- /* fall through */
-
- case NGX_HTTP_IMAGE_PROCESS:
-
- out.buf = ngx_http_image_process(r);
-
- if (out.buf == NULL) {
- return ngx_http_filter_finalize_request(r,
- &ngx_http_image_filter_module,
- NGX_HTTP_UNSUPPORTED_MEDIA_TYPE);
- }
-
- out.next = NULL;
- ctx->phase = NGX_HTTP_IMAGE_PASS;
-
- return ngx_http_image_send(r, ctx, &out);
-
- case NGX_HTTP_IMAGE_PASS:
-
- return ngx_http_next_body_filter(r, in);
-
- default: /* NGX_HTTP_IMAGE_DONE */
-
- rc = ngx_http_next_body_filter(r, NULL);
-
- /* NGX_ERROR resets any pending data */
- return (rc == NGX_OK) ? NGX_ERROR : rc;
- }
-}
-
-
-static ngx_int_t
-ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx,
- ngx_chain_t *in)
-{
- ngx_int_t rc;
-
- rc = ngx_http_next_header_filter(r);
-
- if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
- return NGX_ERROR;
- }
-
- rc = ngx_http_next_body_filter(r, in);
-
- if (ctx->phase == NGX_HTTP_IMAGE_DONE) {
- /* NGX_ERROR resets any pending data */
- return (rc == NGX_OK) ? NGX_ERROR : rc;
- }
-
- return rc;
-}
-
-
-static ngx_uint_t
-ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in)
-{
- u_char *p;
-
- p = in->buf->pos;
-
- if (in->buf->last - p < 16) {
- return NGX_HTTP_IMAGE_NONE;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image filter: \"%c%c\"", p[0], p[1]);
-
- if (p[0] == 0xff && p[1] == 0xd8) {
-
- /* JPEG */
-
- return NGX_HTTP_IMAGE_JPEG;
-
- } else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8'
- && p[5] == 'a')
- {
- if (p[4] == '9' || p[4] == '7') {
- /* GIF */
- return NGX_HTTP_IMAGE_GIF;
- }
-
- } else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G'
- && p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a)
- {
- /* PNG */
-
- return NGX_HTTP_IMAGE_PNG;
-
- } else if (p[0] == 'R' && p[1] == 'I' && p[2] == 'F' && p[3] == 'F'
- && p[8] == 'W' && p[9] == 'E' && p[10] == 'B' && p[11] == 'P')
- {
- /* WebP */
-
- return NGX_HTTP_IMAGE_WEBP;
- }
-
- return NGX_HTTP_IMAGE_NONE;
-}
-
-
-static ngx_int_t
-ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in)
-{
- u_char *p;
- size_t size, rest;
- ngx_buf_t *b;
- ngx_chain_t *cl;
- ngx_http_image_filter_ctx_t *ctx;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- if (ctx->image == NULL) {
- ctx->image = ngx_palloc(r->pool, ctx->length);
- if (ctx->image == NULL) {
- return NGX_ERROR;
- }
-
- ctx->last = ctx->image;
- }
-
- p = ctx->last;
-
- for (cl = in; cl; cl = cl->next) {
-
- b = cl->buf;
- size = b->last - b->pos;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image buf: %uz", size);
-
- rest = ctx->image + ctx->length - p;
-
- if (size > rest) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "image filter: too big response");
- return NGX_ERROR;
- }
-
- p = ngx_cpymem(p, b->pos, size);
- b->pos += size;
-
- if (b->last_buf) {
- ctx->last = p;
- return NGX_OK;
- }
- }
-
- ctx->last = p;
- r->connection->buffered |= NGX_HTTP_IMAGE_BUFFERED;
-
- return NGX_AGAIN;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_process(ngx_http_request_t *r)
-{
- ngx_int_t rc;
- ngx_http_image_filter_ctx_t *ctx;
- ngx_http_image_filter_conf_t *conf;
-
- r->connection->buffered &= ~NGX_HTTP_IMAGE_BUFFERED;
-
- ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module);
-
- rc = ngx_http_image_size(r, ctx);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (conf->filter == NGX_HTTP_IMAGE_SIZE) {
- return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL);
- }
-
- ctx->angle = ngx_http_image_filter_get_value(r, conf->acv, conf->angle);
-
- if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {
-
- if (ctx->angle != 90 && ctx->angle != 180 && ctx->angle != 270) {
- return NULL;
- }
-
- return ngx_http_image_resize(r, ctx);
- }
-
- ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width);
- if (ctx->max_width == 0) {
- return NULL;
- }
-
- ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv,
- conf->height);
- if (ctx->max_height == 0) {
- return NULL;
- }
-
- if (rc == NGX_OK
- && ctx->width <= ctx->max_width
- && ctx->height <= ctx->max_height
- && ctx->angle == 0
- && !ctx->force)
- {
- return ngx_http_image_asis(r, ctx);
- }
-
- return ngx_http_image_resize(r, ctx);
-}
-
-
-static ngx_buf_t *
-ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- size_t len;
- ngx_buf_t *b;
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NULL;
- }
-
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_clean_header(r);
-
- r->headers_out.status = NGX_HTTP_OK;
- r->headers_out.content_type_len = sizeof("application/json") - 1;
- ngx_str_set(&r->headers_out.content_type, "application/json");
- r->headers_out.content_type_lowcase = NULL;
-
- if (ctx == NULL) {
- b->pos = (u_char *) "{}" CRLF;
- b->last = b->pos + sizeof("{}" CRLF) - 1;
-
- ngx_http_image_length(r, b);
-
- return b;
- }
-
- len = sizeof("{ \"img\" : "
- "{ \"width\": , \"height\": , \"type\": \"jpeg\" } }" CRLF) - 1
- + 2 * NGX_SIZE_T_LEN;
-
- b->pos = ngx_pnalloc(r->pool, len);
- if (b->pos == NULL) {
- return NULL;
- }
-
- b->last = ngx_sprintf(b->pos,
- "{ \"img\" : "
- "{ \"width\": %uz,"
- " \"height\": %uz,"
- " \"type\": \"%s\" } }" CRLF,
- ctx->width, ctx->height,
- ngx_http_image_types[ctx->type - 1].data + 6);
-
- ngx_http_image_length(r, b);
-
- return b;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- ngx_buf_t *b;
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- return NULL;
- }
-
- b->pos = ctx->image;
- b->last = ctx->last;
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_image_length(r, b);
-
- return b;
-}
-
-
-static void
-ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b)
-{
- r->headers_out.content_length_n = b->last - b->pos;
-
- if (r->headers_out.content_length) {
- r->headers_out.content_length->hash = 0;
- }
-
- r->headers_out.content_length = NULL;
-}
-
-
-static ngx_int_t
-ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- u_char *p, *last;
- size_t len, app;
- ngx_uint_t width, height;
-
- p = ctx->image;
-
- switch (ctx->type) {
-
- case NGX_HTTP_IMAGE_JPEG:
-
- p += 2;
- last = ctx->image + ctx->length - 10;
- width = 0;
- height = 0;
- app = 0;
-
- while (p < last) {
-
- if (p[0] == 0xff && p[1] != 0xff) {
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "JPEG: %02xd %02xd", p[0], p[1]);
-
- p++;
-
- if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3
- || *p == 0xc9 || *p == 0xca || *p == 0xcb)
- && (width == 0 || height == 0))
- {
- width = p[6] * 256 + p[7];
- height = p[4] * 256 + p[5];
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "JPEG: %02xd %02xd", p[1], p[2]);
-
- len = p[1] * 256 + p[2];
-
- if (*p >= 0xe1 && *p <= 0xef) {
- /* application data, e.g., EXIF, Adobe XMP, etc. */
- app += len;
- }
-
- p += len;
-
- continue;
- }
-
- p++;
- }
-
- if (width == 0 || height == 0) {
- return NGX_DECLINED;
- }
-
- if (ctx->length / 20 < app) {
- /* force conversion if application data consume more than 5% */
- ctx->force = 1;
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "app data size: %uz", app);
- }
-
- break;
-
- case NGX_HTTP_IMAGE_GIF:
-
- if (ctx->length < 10) {
- return NGX_DECLINED;
- }
-
- width = p[7] * 256 + p[6];
- height = p[9] * 256 + p[8];
-
- break;
-
- case NGX_HTTP_IMAGE_PNG:
-
- if (ctx->length < 24) {
- return NGX_DECLINED;
- }
-
- width = p[18] * 256 + p[19];
- height = p[22] * 256 + p[23];
-
- break;
-
- case NGX_HTTP_IMAGE_WEBP:
-
- if (ctx->length < 30) {
- return NGX_DECLINED;
- }
-
- if (p[12] != 'V' || p[13] != 'P' || p[14] != '8') {
- return NGX_DECLINED;
- }
-
- switch (p[15]) {
-
- case ' ':
- if (p[20] & 1) {
- /* not a key frame */
- return NGX_DECLINED;
- }
-
- if (p[23] != 0x9d || p[24] != 0x01 || p[25] != 0x2a) {
- /* invalid start code */
- return NGX_DECLINED;
- }
-
- width = (p[26] | p[27] << 8) & 0x3fff;
- height = (p[28] | p[29] << 8) & 0x3fff;
-
- break;
-
- case 'L':
- if (p[20] != 0x2f) {
- /* invalid signature */
- return NGX_DECLINED;
- }
-
- width = ((p[21] | p[22] << 8) & 0x3fff) + 1;
- height = ((p[22] >> 6 | p[23] << 2 | p[24] << 10) & 0x3fff) + 1;
-
- break;
-
- case 'X':
- width = (p[24] | p[25] << 8 | p[26] << 16) + 1;
- height = (p[27] | p[28] << 8 | p[29] << 16) + 1;
- break;
-
- default:
- return NGX_DECLINED;
- }
-
- break;
-
- default:
-
- return NGX_DECLINED;
- }
-
- ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image size: %d x %d", (int) width, (int) height);
-
- ctx->width = width;
- ctx->height = height;
-
- return NGX_OK;
-}
-
-
-static ngx_buf_t *
-ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- int sx, sy, dx, dy, ox, oy, ax, ay, size,
- colors, palette, transparent, sharpen,
- red, green, blue, t;
- u_char *out;
- ngx_buf_t *b;
- ngx_uint_t resize;
- gdImagePtr src, dst;
- ngx_pool_cleanup_t *cln;
- ngx_http_image_filter_conf_t *conf;
-
- src = ngx_http_image_source(r, ctx);
-
- if (src == NULL) {
- return NULL;
- }
-
- sx = gdImageSX(src);
- sy = gdImageSY(src);
-
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- if (!ctx->force
- && ctx->angle == 0
- && (ngx_uint_t) sx <= ctx->max_width
- && (ngx_uint_t) sy <= ctx->max_height)
- {
- gdImageDestroy(src);
- return ngx_http_image_asis(r, ctx);
- }
-
- colors = gdImageColorsTotal(src);
-
- if (colors && conf->transparency) {
- transparent = gdImageGetTransparent(src);
-
- if (transparent != -1) {
- palette = colors;
- red = gdImageRed(src, transparent);
- green = gdImageGreen(src, transparent);
- blue = gdImageBlue(src, transparent);
-
- goto transparent;
- }
- }
-
- palette = 0;
- transparent = -1;
- red = 0;
- green = 0;
- blue = 0;
-
-transparent:
-
- gdImageColorTransparent(src, -1);
-
- dx = sx;
- dy = sy;
-
- if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
-
- if ((ngx_uint_t) dx > ctx->max_width) {
- dy = dy * ctx->max_width / dx;
- dy = dy ? dy : 1;
- dx = ctx->max_width;
- }
-
- if ((ngx_uint_t) dy > ctx->max_height) {
- dx = dx * ctx->max_height / dy;
- dx = dx ? dx : 1;
- dy = ctx->max_height;
- }
-
- resize = 1;
-
- } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {
-
- resize = 0;
-
- } else { /* NGX_HTTP_IMAGE_CROP */
-
- resize = 0;
-
- if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
- if ((ngx_uint_t) dx > ctx->max_width) {
- dy = dy * ctx->max_width / dx;
- dy = dy ? dy : 1;
- dx = ctx->max_width;
- resize = 1;
- }
-
- } else {
- if ((ngx_uint_t) dy > ctx->max_height) {
- dx = dx * ctx->max_height / dy;
- dx = dx ? dx : 1;
- dy = ctx->max_height;
- resize = 1;
- }
- }
- }
-
- if (resize) {
- dst = ngx_http_image_new(r, dx, dy, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
-
- if (colors == 0) {
- gdImageSaveAlpha(dst, 1);
- gdImageAlphaBlending(dst, 0);
- }
-
- gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);
-
- if (colors) {
- gdImageTrueColorToPalette(dst, 1, 256);
- }
-
- gdImageDestroy(src);
-
- } else {
- dst = src;
- }
-
- if (ctx->angle) {
- src = dst;
-
- ax = (dx % 2 == 0) ? 1 : 0;
- ay = (dy % 2 == 0) ? 1 : 0;
-
- switch (ctx->angle) {
-
- case 90:
- case 270:
- dst = ngx_http_image_new(r, dy, dx, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
- if (ctx->angle == 90) {
- ox = dy / 2 + ay;
- oy = dx / 2 - ax;
-
- } else {
- ox = dy / 2 - ay;
- oy = dx / 2 + ax;
- }
-
- gdImageCopyRotated(dst, src, ox, oy, 0, 0,
- dx + ax, dy + ay, ctx->angle);
- gdImageDestroy(src);
-
- t = dx;
- dx = dy;
- dy = t;
- break;
-
- case 180:
- dst = ngx_http_image_new(r, dx, dy, palette);
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
- gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
- dx + ax, dy + ay, ctx->angle);
- gdImageDestroy(src);
- break;
- }
- }
-
- if (conf->filter == NGX_HTTP_IMAGE_CROP) {
-
- src = dst;
-
- if ((ngx_uint_t) dx > ctx->max_width) {
- ox = dx - ctx->max_width;
-
- } else {
- ox = 0;
- }
-
- if ((ngx_uint_t) dy > ctx->max_height) {
- oy = dy - ctx->max_height;
-
- } else {
- oy = 0;
- }
-
- if (ox || oy) {
-
- dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);
-
- if (dst == NULL) {
- gdImageDestroy(src);
- return NULL;
- }
-
- ox /= 2;
- oy /= 2;
-
- ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image crop: %d x %d @ %d x %d",
- dx, dy, ox, oy);
-
- if (colors == 0) {
- gdImageSaveAlpha(dst, 1);
- gdImageAlphaBlending(dst, 0);
- }
-
- gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
-
- if (colors) {
- gdImageTrueColorToPalette(dst, 1, 256);
- }
-
- gdImageDestroy(src);
- }
- }
-
- if (transparent != -1 && colors) {
- gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
- }
-
- sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
- if (sharpen > 0) {
- gdImageSharpen(dst, sharpen);
- }
-
- gdImageInterlace(dst, (int) conf->interlace);
-
- out = ngx_http_image_out(r, ctx->type, dst, &size);
-
- ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
- "image: %d x %d %d", sx, sy, colors);
-
- gdImageDestroy(dst);
- ngx_pfree(r->pool, ctx->image);
-
- if (out == NULL) {
- return NULL;
- }
-
- cln = ngx_pool_cleanup_add(r->pool, 0);
- if (cln == NULL) {
- gdFree(out);
- return NULL;
- }
-
- b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
- if (b == NULL) {
- gdFree(out);
- return NULL;
- }
-
- cln->handler = ngx_http_image_cleanup;
- cln->data = out;
-
- b->pos = out;
- b->last = out + size;
- b->memory = 1;
- b->last_buf = 1;
-
- ngx_http_image_length(r, b);
- ngx_http_weak_etag(r);
-
- return b;
-}
-
-
-static gdImagePtr
-ngx_http_image_source(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
-{
- char *failed;
- gdImagePtr img;
-
- img = NULL;
-
- switch (ctx->type) {
-
- case NGX_HTTP_IMAGE_JPEG:
- img = gdImageCreateFromJpegPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromJpegPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_GIF:
- img = gdImageCreateFromGifPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromGifPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_PNG:
- img = gdImageCreateFromPngPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromPngPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_WEBP:
-#if (NGX_HAVE_GD_WEBP)
- img = gdImageCreateFromWebpPtr(ctx->length, ctx->image);
- failed = "gdImageCreateFromWebpPtr() failed";
-#else
- failed = "nginx was built without GD WebP support";
-#endif
- break;
-
- default:
- failed = "unknown image type";
- break;
- }
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed);
- }
-
- return img;
-}
-
-
-static gdImagePtr
-ngx_http_image_new(ngx_http_request_t *r, int w, int h, int colors)
-{
- gdImagePtr img;
-
- if (colors == 0) {
- img = gdImageCreateTrueColor(w, h);
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "gdImageCreateTrueColor() failed");
- return NULL;
- }
-
- } else {
- img = gdImageCreate(w, h);
-
- if (img == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
- "gdImageCreate() failed");
- return NULL;
- }
- }
-
- return img;
-}
-
-
-static u_char *
-ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img,
- int *size)
-{
- char *failed;
- u_char *out;
- ngx_int_t q;
- ngx_http_image_filter_conf_t *conf;
-
- out = NULL;
-
- switch (type) {
-
- case NGX_HTTP_IMAGE_JPEG:
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- q = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality);
- if (q <= 0) {
- return NULL;
- }
-
- out = gdImageJpegPtr(img, size, q);
- failed = "gdImageJpegPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_GIF:
- out = gdImageGifPtr(img, size);
- failed = "gdImageGifPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_PNG:
- out = gdImagePngPtr(img, size);
- failed = "gdImagePngPtr() failed";
- break;
-
- case NGX_HTTP_IMAGE_WEBP:
-#if (NGX_HAVE_GD_WEBP)
- conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);
-
- q = ngx_http_image_filter_get_value(r, conf->wqcv, conf->webp_quality);
- if (q <= 0) {
- return NULL;
- }
-
- out = gdImageWebpPtrEx(img, size, q);
- failed = "gdImageWebpPtrEx() failed";
-#else
- failed = "nginx was built without GD WebP support";
-#endif
- break;
-
- default:
- failed = "unknown image type";
- break;
- }
-
- if (out == NULL) {
- ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed);
- }
-
- return out;
-}
-
-
-static void
-ngx_http_image_cleanup(void *data)
-{
- gdFree(data);
-}
-
-
-static ngx_uint_t
-ngx_http_image_filter_get_value(ngx_http_request_t *r,
- ngx_http_complex_value_t *cv, ngx_uint_t v)
-{
- ngx_str_t val;
-
- if (cv == NULL) {
- return v;
- }
-
- if (ngx_http_complex_value(r, cv, &val) != NGX_OK) {
- return 0;
- }
-
- return ngx_http_image_filter_value(&val);
-}
-
-
-static ngx_uint_t
-ngx_http_image_filter_value(ngx_str_t *value)
-{
- ngx_int_t n;
-
- if (value->len == 1 && value->data[0] == '-') {
- return (ngx_uint_t) -1;
- }
-
- n = ngx_atoi(value->data, value->len);
-
- if (n > 0) {
- return (ngx_uint_t) n;
- }
-
- return 0;
-}
-
-
-static void *
-ngx_http_image_filter_create_conf(ngx_conf_t *cf)
-{
- ngx_http_image_filter_conf_t *conf;
-
- conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t));
- if (conf == NULL) {
- return NULL;
- }
-
- /*
- * set by ngx_pcalloc():
- *
- * conf->width = 0;
- * conf->height = 0;
- * conf->angle = 0;
- * conf->wcv = NULL;
- * conf->hcv = NULL;
- * conf->acv = NULL;
- * conf->jqcv = NULL;
- * conf->wqcv = NULL;
- * conf->shcv = NULL;
- */
-
- conf->filter = NGX_CONF_UNSET_UINT;
- conf->jpeg_quality = NGX_CONF_UNSET_UINT;
- conf->webp_quality = NGX_CONF_UNSET_UINT;
- conf->sharpen = NGX_CONF_UNSET_UINT;
- conf->transparency = NGX_CONF_UNSET;
- conf->interlace = NGX_CONF_UNSET;
- conf->buffer_size = NGX_CONF_UNSET_SIZE;
-
- return conf;
-}
-
-
-static char *
-ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
-{
- ngx_http_image_filter_conf_t *prev = parent;
- ngx_http_image_filter_conf_t *conf = child;
-
- if (conf->filter == NGX_CONF_UNSET_UINT) {
-
- if (prev->filter == NGX_CONF_UNSET_UINT) {
- conf->filter = NGX_HTTP_IMAGE_OFF;
-
- } else {
- conf->filter = prev->filter;
- conf->width = prev->width;
- conf->height = prev->height;
- conf->angle = prev->angle;
- conf->wcv = prev->wcv;
- conf->hcv = prev->hcv;
- conf->acv = prev->acv;
- }
- }
-
- if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) {
-
- /* 75 is libjpeg default quality */
- ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75);
-
- if (conf->jqcv == NULL) {
- conf->jqcv = prev->jqcv;
- }
- }
-
- if (conf->webp_quality == NGX_CONF_UNSET_UINT) {
-
- /* 80 is libwebp default quality */
- ngx_conf_merge_uint_value(conf->webp_quality, prev->webp_quality, 80);
-
- if (conf->wqcv == NULL) {
- conf->wqcv = prev->wqcv;
- }
- }
-
- if (conf->sharpen == NGX_CONF_UNSET_UINT) {
- ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0);
-
- if (conf->shcv == NULL) {
- conf->shcv = prev->shcv;
- }
- }
-
- ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
-
- ngx_conf_merge_value(conf->interlace, prev->interlace, 0);
-
- ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
- 1 * 1024 * 1024);
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_uint_t i;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- i = 1;
-
- if (cf->args->nelts == 2) {
- if (ngx_strcmp(value[i].data, "off") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_OFF;
-
- } else if (ngx_strcmp(value[i].data, "test") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_TEST;
-
- } else if (ngx_strcmp(value[i].data, "size") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_SIZE;
-
- } else {
- goto failed;
- }
-
- return NGX_CONF_OK;
-
- } else if (cf->args->nelts == 3) {
-
- if (ngx_strcmp(value[i].data, "rotate") == 0) {
- if (imcf->filter != NGX_HTTP_IMAGE_RESIZE
- && imcf->filter != NGX_HTTP_IMAGE_CROP)
- {
- imcf->filter = NGX_HTTP_IMAGE_ROTATE;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n != 90 && n != 180 && n != 270) {
- goto failed;
- }
-
- imcf->angle = (ngx_uint_t) n;
-
- } else {
- imcf->acv = ngx_palloc(cf->pool,
- sizeof(ngx_http_complex_value_t));
- if (imcf->acv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->acv = cv;
- }
-
- return NGX_CONF_OK;
-
- } else {
- goto failed;
- }
- }
-
- if (ngx_strcmp(value[i].data, "resize") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_RESIZE;
-
- } else if (ngx_strcmp(value[i].data, "crop") == 0) {
- imcf->filter = NGX_HTTP_IMAGE_CROP;
-
- } else {
- goto failed;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n == 0) {
- goto failed;
- }
-
- imcf->width = (ngx_uint_t) n;
-
- } else {
- imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->wcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->wcv = cv;
- }
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[++i];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[i]);
-
- if (n == 0) {
- goto failed;
- }
-
- imcf->height = (ngx_uint_t) n;
-
- } else {
- imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->hcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->hcv = cv;
- }
-
- return NGX_CONF_OK;
-
-failed:
-
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"",
- &value[i]);
-
- return NGX_CONF_ERROR;
-}
-
-
-static char *
-ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[1]);
-
- if (n <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- imcf->jpeg_quality = (ngx_uint_t) n;
-
- } else {
- imcf->jqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->jqcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->jqcv = cv;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_image_filter_webp_quality(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[1]);
-
- if (n <= 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- imcf->webp_quality = (ngx_uint_t) n;
-
- } else {
- imcf->wqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->wqcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->wqcv = cv;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static char *
-ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd,
- void *conf)
-{
- ngx_http_image_filter_conf_t *imcf = conf;
-
- ngx_str_t *value;
- ngx_int_t n;
- ngx_http_complex_value_t cv;
- ngx_http_compile_complex_value_t ccv;
-
- value = cf->args->elts;
-
- ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
-
- ccv.cf = cf;
- ccv.value = &value[1];
- ccv.complex_value = &cv;
-
- if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
- return NGX_CONF_ERROR;
- }
-
- if (cv.lengths == NULL) {
- n = ngx_http_image_filter_value(&value[1]);
-
- if (n < 0) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid value \"%V\"", &value[1]);
- return NGX_CONF_ERROR;
- }
-
- imcf->sharpen = (ngx_uint_t) n;
-
- } else {
- imcf->shcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t));
- if (imcf->shcv == NULL) {
- return NGX_CONF_ERROR;
- }
-
- *imcf->shcv = cv;
- }
-
- return NGX_CONF_OK;
-}
-
-
-static ngx_int_t
-ngx_http_image_filter_init(ngx_conf_t *cf)
-{
- ngx_http_next_header_filter = ngx_http_top_header_filter;
- ngx_http_top_header_filter = ngx_http_image_header_filter;
-
- ngx_http_next_body_filter = ngx_http_top_body_filter;
- ngx_http_top_body_filter = ngx_http_image_body_filter;
-
- return NGX_OK;
-}