Mercurial > hg > nginx
annotate src/http/modules/ngx_http_image_filter_module.c @ 5204:a64c8a5da336
PCRE: retain input pattern for all regular expressions.
Previously, input pattern was kept only for regular expressions
with named captures, which resulted in error log entries without
input pattern for PCRE errors that occured while processing
regular expressions without them.
Signed-off-by: Piotr Sikora <piotr@cloudflare.com>
author | Piotr Sikora <piotr@cloudflare.com> |
---|---|
date | Thu, 02 May 2013 03:26:36 -0700 |
parents | af155fc41deb |
children | 31932b5464f0 |
rev | line source |
---|---|
2788 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4412 | 4 * Copyright (C) Nginx, Inc. |
2788 | 5 */ |
6 | |
7 | |
8 #include <ngx_config.h> | |
9 #include <ngx_core.h> | |
10 #include <ngx_http.h> | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
11 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
12 #include <gd.h> |
2788 | 13 |
14 | |
15 #define NGX_HTTP_IMAGE_OFF 0 | |
16 #define NGX_HTTP_IMAGE_TEST 1 | |
17 #define NGX_HTTP_IMAGE_SIZE 2 | |
18 #define NGX_HTTP_IMAGE_RESIZE 3 | |
19 #define NGX_HTTP_IMAGE_CROP 4 | |
3878 | 20 #define NGX_HTTP_IMAGE_ROTATE 5 |
2788 | 21 |
22 | |
23 #define NGX_HTTP_IMAGE_START 0 | |
24 #define NGX_HTTP_IMAGE_READ 1 | |
25 #define NGX_HTTP_IMAGE_PROCESS 2 | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
26 #define NGX_HTTP_IMAGE_PASS 3 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
27 #define NGX_HTTP_IMAGE_DONE 4 |
2788 | 28 |
29 | |
30 #define NGX_HTTP_IMAGE_NONE 0 | |
31 #define NGX_HTTP_IMAGE_JPEG 1 | |
32 #define NGX_HTTP_IMAGE_GIF 2 | |
33 #define NGX_HTTP_IMAGE_PNG 3 | |
34 | |
35 | |
36 #define NGX_HTTP_IMAGE_BUFFERED 0x08 | |
37 | |
38 | |
39 typedef struct { | |
40 ngx_uint_t filter; | |
41 ngx_uint_t width; | |
42 ngx_uint_t height; | |
3878 | 43 ngx_uint_t angle; |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
44 ngx_uint_t jpeg_quality; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
45 ngx_uint_t sharpen; |
2788 | 46 |
3134 | 47 ngx_flag_t transparency; |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
48 ngx_flag_t interlace; |
3134 | 49 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
50 ngx_http_complex_value_t *wcv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
51 ngx_http_complex_value_t *hcv; |
3878 | 52 ngx_http_complex_value_t *acv; |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
53 ngx_http_complex_value_t *jqcv; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
54 ngx_http_complex_value_t *shcv; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
55 |
2788 | 56 size_t buffer_size; |
57 } ngx_http_image_filter_conf_t; | |
58 | |
59 | |
60 typedef struct { | |
61 u_char *image; | |
62 u_char *last; | |
63 | |
64 size_t length; | |
65 | |
66 ngx_uint_t width; | |
67 ngx_uint_t height; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
68 ngx_uint_t max_width; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
69 ngx_uint_t max_height; |
3878 | 70 ngx_uint_t angle; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
71 |
2788 | 72 ngx_uint_t phase; |
73 ngx_uint_t type; | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
74 ngx_uint_t force; |
2788 | 75 } ngx_http_image_filter_ctx_t; |
76 | |
77 | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
78 static ngx_int_t ngx_http_image_send(ngx_http_request_t *r, |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
79 ngx_http_image_filter_ctx_t *ctx, ngx_chain_t *in); |
2788 | 80 static ngx_uint_t ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in); |
81 static ngx_int_t ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in); | |
82 static ngx_buf_t *ngx_http_image_process(ngx_http_request_t *r); | |
83 static ngx_buf_t *ngx_http_image_json(ngx_http_request_t *r, | |
84 ngx_http_image_filter_ctx_t *ctx); | |
85 static ngx_buf_t *ngx_http_image_asis(ngx_http_request_t *r, | |
86 ngx_http_image_filter_ctx_t *ctx); | |
87 static void ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b); | |
88 static ngx_int_t ngx_http_image_size(ngx_http_request_t *r, | |
89 ngx_http_image_filter_ctx_t *ctx); | |
90 | |
91 static ngx_buf_t *ngx_http_image_resize(ngx_http_request_t *r, | |
92 ngx_http_image_filter_ctx_t *ctx); | |
93 static gdImagePtr ngx_http_image_source(ngx_http_request_t *r, | |
94 ngx_http_image_filter_ctx_t *ctx); | |
95 static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h, | |
96 int colors); | |
97 static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, | |
98 gdImagePtr img, int *size); | |
99 static void ngx_http_image_cleanup(void *data); | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
100 static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r, |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
101 ngx_http_complex_value_t *cv, ngx_uint_t v); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
102 static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value); |
2788 | 103 |
104 | |
105 static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); | |
106 static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, | |
107 void *child); | |
108 static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, | |
109 void *conf); | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
110 static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
111 ngx_command_t *cmd, void *conf); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
112 static char *ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
113 void *conf); |
2788 | 114 static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf); |
115 | |
116 | |
117 static ngx_command_t ngx_http_image_filter_commands[] = { | |
118 | |
119 { ngx_string("image_filter"), | |
4307 | 120 NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123, |
2788 | 121 ngx_http_image_filter, |
122 NGX_HTTP_LOC_CONF_OFFSET, | |
123 0, | |
124 NULL }, | |
125 | |
2848 | 126 { ngx_string("image_filter_jpeg_quality"), |
127 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
128 ngx_http_image_filter_jpeg_quality, |
2848 | 129 NGX_HTTP_LOC_CONF_OFFSET, |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
130 0, |
2848 | 131 NULL }, |
132 | |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
133 { ngx_string("image_filter_sharpen"), |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
134 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
135 ngx_http_image_filter_sharpen, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
136 NGX_HTTP_LOC_CONF_OFFSET, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
137 0, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
138 NULL }, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
139 |
3134 | 140 { ngx_string("image_filter_transparency"), |
141 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
142 ngx_conf_set_flag_slot, | |
143 NGX_HTTP_LOC_CONF_OFFSET, | |
144 offsetof(ngx_http_image_filter_conf_t, transparency), | |
145 NULL }, | |
146 | |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
147 { ngx_string("image_filter_interlace"), |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
148 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
149 ngx_conf_set_flag_slot, |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
150 NGX_HTTP_LOC_CONF_OFFSET, |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
151 offsetof(ngx_http_image_filter_conf_t, interlace), |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
152 NULL }, |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
153 |
2788 | 154 { ngx_string("image_filter_buffer"), |
155 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
156 ngx_conf_set_size_slot, | |
157 NGX_HTTP_LOC_CONF_OFFSET, | |
158 offsetof(ngx_http_image_filter_conf_t, buffer_size), | |
159 NULL }, | |
160 | |
161 ngx_null_command | |
162 }; | |
163 | |
164 | |
165 static ngx_http_module_t ngx_http_image_filter_module_ctx = { | |
166 NULL, /* preconfiguration */ | |
167 ngx_http_image_filter_init, /* postconfiguration */ | |
168 | |
169 NULL, /* create main configuration */ | |
170 NULL, /* init main configuration */ | |
171 | |
172 NULL, /* create server configuration */ | |
173 NULL, /* merge server configuration */ | |
174 | |
175 ngx_http_image_filter_create_conf, /* create location configuration */ | |
176 ngx_http_image_filter_merge_conf /* merge location configuration */ | |
177 }; | |
178 | |
179 | |
180 ngx_module_t ngx_http_image_filter_module = { | |
181 NGX_MODULE_V1, | |
182 &ngx_http_image_filter_module_ctx, /* module context */ | |
183 ngx_http_image_filter_commands, /* module directives */ | |
184 NGX_HTTP_MODULE, /* module type */ | |
185 NULL, /* init master */ | |
186 NULL, /* init module */ | |
187 NULL, /* init process */ | |
188 NULL, /* init thread */ | |
189 NULL, /* exit thread */ | |
190 NULL, /* exit process */ | |
191 NULL, /* exit master */ | |
192 NGX_MODULE_V1_PADDING | |
193 }; | |
194 | |
195 | |
196 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
197 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
198 | |
199 | |
200 static ngx_str_t ngx_http_image_types[] = { | |
201 ngx_string("image/jpeg"), | |
202 ngx_string("image/gif"), | |
203 ngx_string("image/png") | |
204 }; | |
205 | |
206 | |
207 static ngx_int_t | |
208 ngx_http_image_header_filter(ngx_http_request_t *r) | |
209 { | |
210 off_t len; | |
211 ngx_http_image_filter_ctx_t *ctx; | |
212 ngx_http_image_filter_conf_t *conf; | |
213 | |
214 if (r->headers_out.status == NGX_HTTP_NOT_MODIFIED) { | |
215 return ngx_http_next_header_filter(r); | |
216 } | |
217 | |
2834
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
218 ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module); |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
219 |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
220 if (ctx) { |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
221 ngx_http_set_ctx(r, NULL, ngx_http_image_filter_module); |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
222 return ngx_http_next_header_filter(r); |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
223 } |
0449d289256c
test finalized image filter context before testing image_filter off
Igor Sysoev <igor@sysoev.ru>
parents:
2821
diff
changeset
|
224 |
2788 | 225 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
226 | |
227 if (conf->filter == NGX_HTTP_IMAGE_OFF) { | |
228 return ngx_http_next_header_filter(r); | |
229 } | |
230 | |
231 if (r->headers_out.content_type.len | |
232 >= sizeof("multipart/x-mixed-replace") - 1 | |
233 && ngx_strncasecmp(r->headers_out.content_type.data, | |
234 (u_char *) "multipart/x-mixed-replace", | |
235 sizeof("multipart/x-mixed-replace") - 1) | |
236 == 0) | |
237 { | |
238 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
239 "image filter: multipart/x-mixed-replace response"); | |
240 | |
241 return NGX_ERROR; | |
242 } | |
243 | |
244 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_image_filter_ctx_t)); | |
245 if (ctx == NULL) { | |
246 return NGX_ERROR; | |
247 } | |
248 | |
249 ngx_http_set_ctx(r, ctx, ngx_http_image_filter_module); | |
250 | |
251 len = r->headers_out.content_length_n; | |
252 | |
2795
d82d08314f78
fix building ngx_http_image_filter_module on 64-bit platforms
Igor Sysoev <igor@sysoev.ru>
parents:
2788
diff
changeset
|
253 if (len != -1 && len > (off_t) conf->buffer_size) { |
2788 | 254 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
255 "image filter: too big response: %O", len); | |
256 | |
3722
1a728cc43bb1
return 415 on too big image in image filter
Igor Sysoev <igor@sysoev.ru>
parents:
3516
diff
changeset
|
257 return NGX_HTTP_UNSUPPORTED_MEDIA_TYPE; |
2788 | 258 } |
259 | |
260 if (len == -1) { | |
261 ctx->length = conf->buffer_size; | |
262 | |
263 } else { | |
264 ctx->length = (size_t) len; | |
265 } | |
266 | |
267 if (r->headers_out.refresh) { | |
268 r->headers_out.refresh->hash = 0; | |
269 } | |
270 | |
271 r->main_filter_need_in_memory = 1; | |
272 r->allow_ranges = 0; | |
273 | |
274 return NGX_OK; | |
275 } | |
276 | |
277 | |
278 static ngx_int_t | |
279 ngx_http_image_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
280 { | |
281 ngx_int_t rc; | |
282 ngx_str_t *ct; | |
283 ngx_chain_t out; | |
284 ngx_http_image_filter_ctx_t *ctx; | |
285 ngx_http_image_filter_conf_t *conf; | |
286 | |
287 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "image filter"); | |
288 | |
289 if (in == NULL) { | |
290 return ngx_http_next_body_filter(r, in); | |
291 } | |
292 | |
293 ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module); | |
294 | |
295 if (ctx == NULL) { | |
296 return ngx_http_next_body_filter(r, in); | |
297 } | |
298 | |
299 switch (ctx->phase) { | |
300 | |
301 case NGX_HTTP_IMAGE_START: | |
302 | |
303 ctx->type = ngx_http_image_test(r, in); | |
304 | |
305 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | |
306 | |
307 if (ctx->type == NGX_HTTP_IMAGE_NONE) { | |
308 | |
309 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { | |
310 out.buf = ngx_http_image_json(r, NULL); | |
311 | |
312 if (out.buf) { | |
313 out.next = NULL; | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
314 ctx->phase = NGX_HTTP_IMAGE_DONE; |
2788 | 315 |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
316 return ngx_http_image_send(r, ctx, &out); |
2788 | 317 } |
318 } | |
319 | |
320 return ngx_http_filter_finalize_request(r, | |
2821
26e06e009ced
allow to pass image filter errors via the same location where the filter is set
Igor Sysoev <igor@sysoev.ru>
parents:
2819
diff
changeset
|
321 &ngx_http_image_filter_module, |
2788 | 322 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); |
323 } | |
324 | |
325 /* override content type */ | |
326 | |
327 ct = &ngx_http_image_types[ctx->type - 1]; | |
328 r->headers_out.content_type_len = ct->len; | |
329 r->headers_out.content_type = *ct; | |
2882
896db5a09bd2
reset content_type hash value, this fixes a bug when XSLT responses
Igor Sysoev <igor@sysoev.ru>
parents:
2848
diff
changeset
|
330 r->headers_out.content_type_lowcase = NULL; |
2788 | 331 |
332 if (conf->filter == NGX_HTTP_IMAGE_TEST) { | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
333 ctx->phase = NGX_HTTP_IMAGE_PASS; |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
334 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
335 return ngx_http_image_send(r, ctx, in); |
2788 | 336 } |
337 | |
338 ctx->phase = NGX_HTTP_IMAGE_READ; | |
339 | |
340 /* fall through */ | |
341 | |
342 case NGX_HTTP_IMAGE_READ: | |
343 | |
344 rc = ngx_http_image_read(r, in); | |
345 | |
346 if (rc == NGX_AGAIN) { | |
347 return NGX_OK; | |
348 } | |
349 | |
350 if (rc == NGX_ERROR) { | |
351 return ngx_http_filter_finalize_request(r, | |
2821
26e06e009ced
allow to pass image filter errors via the same location where the filter is set
Igor Sysoev <igor@sysoev.ru>
parents:
2819
diff
changeset
|
352 &ngx_http_image_filter_module, |
2788 | 353 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); |
354 } | |
355 | |
356 /* fall through */ | |
357 | |
358 case NGX_HTTP_IMAGE_PROCESS: | |
359 | |
360 out.buf = ngx_http_image_process(r); | |
361 | |
362 if (out.buf == NULL) { | |
363 return ngx_http_filter_finalize_request(r, | |
2821
26e06e009ced
allow to pass image filter errors via the same location where the filter is set
Igor Sysoev <igor@sysoev.ru>
parents:
2819
diff
changeset
|
364 &ngx_http_image_filter_module, |
2788 | 365 NGX_HTTP_UNSUPPORTED_MEDIA_TYPE); |
366 } | |
367 | |
368 out.next = NULL; | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
369 ctx->phase = NGX_HTTP_IMAGE_PASS; |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
370 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
371 return ngx_http_image_send(r, ctx, &out); |
2788 | 372 |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
373 case NGX_HTTP_IMAGE_PASS: |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
374 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
375 return ngx_http_next_body_filter(r, in); |
2788 | 376 |
377 default: /* NGX_HTTP_IMAGE_DONE */ | |
378 | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
379 rc = ngx_http_next_body_filter(r, NULL); |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
380 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
381 /* NGX_ERROR resets any pending data */ |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
382 return (rc == NGX_OK) ? NGX_ERROR : rc; |
2788 | 383 } |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
384 } |
2788 | 385 |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
386 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
387 static ngx_int_t |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
388 ngx_http_image_send(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx, |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
389 ngx_chain_t *in) |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
390 { |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
391 ngx_int_t rc; |
2788 | 392 |
393 rc = ngx_http_next_header_filter(r); | |
394 | |
395 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
396 return NGX_ERROR; |
2788 | 397 } |
398 | |
2819
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
399 rc = ngx_http_next_body_filter(r, in); |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
400 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
401 if (ctx->phase == NGX_HTTP_IMAGE_DONE) { |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
402 /* NGX_ERROR resets any pending data */ |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
403 return (rc == NGX_OK) ? NGX_ERROR : rc; |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
404 } |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
405 |
43fe53832da7
handle big responses for "size" and "test" image_filters
Igor Sysoev <igor@sysoev.ru>
parents:
2795
diff
changeset
|
406 return rc; |
2788 | 407 } |
408 | |
409 | |
410 static ngx_uint_t | |
411 ngx_http_image_test(ngx_http_request_t *r, ngx_chain_t *in) | |
412 { | |
413 u_char *p; | |
414 | |
415 p = in->buf->pos; | |
416 | |
417 if (in->buf->last - p < 16) { | |
418 return NGX_HTTP_IMAGE_NONE; | |
419 } | |
420 | |
421 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
422 "image filter: \"%c%c\"", p[0], p[1]); | |
423 | |
424 if (p[0] == 0xff && p[1] == 0xd8) { | |
425 | |
426 /* JPEG */ | |
427 | |
428 return NGX_HTTP_IMAGE_JPEG; | |
429 | |
430 } else if (p[0] == 'G' && p[1] == 'I' && p[2] == 'F' && p[3] == '8' | |
2918 | 431 && p[5] == 'a') |
2788 | 432 { |
2918 | 433 if (p[4] == '9' || p[4] == '7') { |
434 /* GIF */ | |
435 return NGX_HTTP_IMAGE_GIF; | |
436 } | |
2788 | 437 |
438 } else if (p[0] == 0x89 && p[1] == 'P' && p[2] == 'N' && p[3] == 'G' | |
439 && p[4] == 0x0d && p[5] == 0x0a && p[6] == 0x1a && p[7] == 0x0a) | |
440 { | |
441 /* PNG */ | |
442 | |
443 return NGX_HTTP_IMAGE_PNG; | |
444 } | |
445 | |
446 return NGX_HTTP_IMAGE_NONE; | |
447 } | |
448 | |
449 | |
450 static ngx_int_t | |
451 ngx_http_image_read(ngx_http_request_t *r, ngx_chain_t *in) | |
452 { | |
453 u_char *p; | |
454 size_t size, rest; | |
455 ngx_buf_t *b; | |
456 ngx_chain_t *cl; | |
457 ngx_http_image_filter_ctx_t *ctx; | |
458 | |
459 ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module); | |
460 | |
461 if (ctx->image == NULL) { | |
462 ctx->image = ngx_palloc(r->pool, ctx->length); | |
463 if (ctx->image == NULL) { | |
464 return NGX_ERROR; | |
465 } | |
466 | |
467 ctx->last = ctx->image; | |
468 } | |
469 | |
470 p = ctx->last; | |
471 | |
472 for (cl = in; cl; cl = cl->next) { | |
473 | |
474 b = cl->buf; | |
475 size = b->last - b->pos; | |
476 | |
477 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
478 "image buf: %uz", size); | |
479 | |
480 rest = ctx->image + ctx->length - p; | |
481 size = (rest < size) ? rest : size; | |
482 | |
483 p = ngx_cpymem(p, b->pos, size); | |
484 b->pos += size; | |
485 | |
486 if (b->last_buf) { | |
487 ctx->last = p; | |
488 return NGX_OK; | |
489 } | |
490 } | |
491 | |
492 ctx->last = p; | |
493 r->connection->buffered |= NGX_HTTP_IMAGE_BUFFERED; | |
494 | |
495 return NGX_AGAIN; | |
496 } | |
497 | |
498 | |
499 static ngx_buf_t * | |
500 ngx_http_image_process(ngx_http_request_t *r) | |
501 { | |
502 ngx_int_t rc; | |
503 ngx_http_image_filter_ctx_t *ctx; | |
504 ngx_http_image_filter_conf_t *conf; | |
505 | |
506 r->connection->buffered &= ~NGX_HTTP_IMAGE_BUFFERED; | |
507 | |
508 ctx = ngx_http_get_module_ctx(r, ngx_http_image_filter_module); | |
509 | |
510 rc = ngx_http_image_size(r, ctx); | |
511 | |
512 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | |
513 | |
514 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
515 return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
516 } |
2788 | 517 |
3878 | 518 ctx->angle = ngx_http_image_filter_get_value(r, conf->acv, conf->angle); |
519 | |
520 if (conf->filter == NGX_HTTP_IMAGE_ROTATE) { | |
521 | |
522 if (ctx->angle != 90 && ctx->angle != 180 && ctx->angle != 270) { | |
523 return NULL; | |
524 } | |
525 | |
526 return ngx_http_image_resize(r, ctx); | |
527 } | |
528 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
529 ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
530 if (ctx->max_width == 0) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
531 return NULL; |
2788 | 532 } |
533 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
534 ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv, |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
535 conf->height); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
536 if (ctx->max_height == 0) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
537 return NULL; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
538 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
539 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
540 if (rc == NGX_OK |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
541 && ctx->width <= ctx->max_width |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
542 && ctx->height <= ctx->max_height |
3878 | 543 && ctx->angle == 0 |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
544 && !ctx->force) |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
545 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
546 return ngx_http_image_asis(r, ctx); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
547 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
548 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
549 return ngx_http_image_resize(r, ctx); |
2788 | 550 } |
551 | |
552 | |
553 static ngx_buf_t * | |
554 ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
555 { | |
556 size_t len; | |
557 ngx_buf_t *b; | |
558 | |
559 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
560 if (b == NULL) { | |
561 return NULL; | |
562 } | |
563 | |
564 b->memory = 1; | |
565 b->last_buf = 1; | |
566 | |
567 ngx_http_clean_header(r); | |
568 | |
569 r->headers_out.status = NGX_HTTP_OK; | |
3516
dd1570b6f237
ngx_str_set() and ngx_str_null()
Igor Sysoev <igor@sysoev.ru>
parents:
3394
diff
changeset
|
570 ngx_str_set(&r->headers_out.content_type, "text/plain"); |
2882
896db5a09bd2
reset content_type hash value, this fixes a bug when XSLT responses
Igor Sysoev <igor@sysoev.ru>
parents:
2848
diff
changeset
|
571 r->headers_out.content_type_lowcase = NULL; |
2788 | 572 |
573 if (ctx == NULL) { | |
574 b->pos = (u_char *) "{}" CRLF; | |
575 b->last = b->pos + sizeof("{}" CRLF) - 1; | |
576 | |
577 ngx_http_image_length(r, b); | |
578 | |
579 return b; | |
580 } | |
581 | |
582 len = sizeof("{ \"img\" : " | |
583 "{ \"width\": , \"height\": , \"type\": \"jpeg\" } }" CRLF) - 1 | |
584 + 2 * NGX_SIZE_T_LEN; | |
585 | |
586 b->pos = ngx_pnalloc(r->pool, len); | |
587 if (b->pos == NULL) { | |
588 return NULL; | |
589 } | |
590 | |
591 b->last = ngx_sprintf(b->pos, | |
592 "{ \"img\" : " | |
593 "{ \"width\": %uz," | |
594 " \"height\": %uz," | |
595 " \"type\": \"%s\" } }" CRLF, | |
596 ctx->width, ctx->height, | |
597 ngx_http_image_types[ctx->type - 1].data + 6); | |
598 | |
599 ngx_http_image_length(r, b); | |
600 | |
601 return b; | |
602 } | |
603 | |
604 | |
605 static ngx_buf_t * | |
606 ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
607 { | |
608 ngx_buf_t *b; | |
609 | |
610 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
611 if (b == NULL) { | |
612 return NULL; | |
613 } | |
614 | |
615 b->pos = ctx->image; | |
616 b->last = ctx->last; | |
617 b->memory = 1; | |
618 b->last_buf = 1; | |
619 | |
620 ngx_http_image_length(r, b); | |
621 | |
622 return b; | |
623 } | |
624 | |
625 | |
626 static void | |
627 ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b) | |
628 { | |
629 r->headers_out.content_length_n = b->last - b->pos; | |
630 | |
631 if (r->headers_out.content_length) { | |
632 r->headers_out.content_length->hash = 0; | |
633 } | |
634 | |
635 r->headers_out.content_length = NULL; | |
636 } | |
637 | |
638 | |
639 static ngx_int_t | |
640 ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
641 { | |
642 u_char *p, *last; | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
643 size_t len, app; |
2788 | 644 ngx_uint_t width, height; |
645 | |
646 p = ctx->image; | |
647 | |
648 switch (ctx->type) { | |
649 | |
650 case NGX_HTTP_IMAGE_JPEG: | |
651 | |
652 p += 2; | |
653 last = ctx->image + ctx->length - 10; | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
654 width = 0; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
655 height = 0; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
656 app = 0; |
2788 | 657 |
658 while (p < last) { | |
659 | |
660 if (p[0] == 0xff && p[1] != 0xff) { | |
661 | |
662 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
3393 | 663 "JPEG: %02xd %02xd", p[0], p[1]); |
2788 | 664 |
665 p++; | |
666 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
667 if ((*p == 0xc0 || *p == 0xc1 || *p == 0xc2 || *p == 0xc3 |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
668 || *p == 0xc9 || *p == 0xca || *p == 0xcb) |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
669 && (width == 0 || height == 0)) |
2788 | 670 { |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
671 width = p[6] * 256 + p[7]; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
672 height = p[4] * 256 + p[5]; |
2788 | 673 } |
674 | |
675 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
676 "JPEG: %02xd %02xd", p[1], p[2]); | |
677 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
678 len = p[1] * 256 + p[2]; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
679 |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
680 if (*p >= 0xe1 && *p <= 0xef) { |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
681 /* application data, e.g., EXIF, Adobe XMP, etc. */ |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
682 app += len; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
683 } |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
684 |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
685 p += len; |
2788 | 686 |
687 continue; | |
688 } | |
689 | |
690 p++; | |
691 } | |
692 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
693 if (width == 0 || height == 0) { |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
694 return NGX_DECLINED; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
695 } |
2788 | 696 |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
697 if (ctx->length / 20 < app) { |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
698 /* force conversion if application data consume more than 5% */ |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
699 ctx->force = 1; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
700 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
701 "app data size: %uz", app); |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
702 } |
2788 | 703 |
704 break; | |
705 | |
706 case NGX_HTTP_IMAGE_GIF: | |
707 | |
708 if (ctx->length < 10) { | |
709 return NGX_DECLINED; | |
710 } | |
711 | |
712 width = p[7] * 256 + p[6]; | |
713 height = p[9] * 256 + p[8]; | |
714 | |
715 break; | |
716 | |
717 case NGX_HTTP_IMAGE_PNG: | |
718 | |
719 if (ctx->length < 24) { | |
720 return NGX_DECLINED; | |
721 } | |
722 | |
723 width = p[18] * 256 + p[19]; | |
724 height = p[22] * 256 + p[23]; | |
725 | |
726 break; | |
727 | |
728 default: | |
729 | |
730 return NGX_DECLINED; | |
731 } | |
732 | |
733 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
734 "image size: %d x %d", width, height); | |
735 | |
736 ctx->width = width; | |
737 ctx->height = height; | |
738 | |
739 return NGX_OK; | |
740 } | |
741 | |
742 | |
743 static ngx_buf_t * | |
744 ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
745 { | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
746 int sx, sy, dx, dy, ox, oy, ax, ay, size, |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
747 colors, palette, transparent, sharpen, |
3878 | 748 red, green, blue, t; |
2788 | 749 u_char *out; |
750 ngx_buf_t *b; | |
751 ngx_uint_t resize; | |
752 gdImagePtr src, dst; | |
753 ngx_pool_cleanup_t *cln; | |
754 ngx_http_image_filter_conf_t *conf; | |
755 | |
756 src = ngx_http_image_source(r, ctx); | |
757 | |
758 if (src == NULL) { | |
759 return NULL; | |
760 } | |
761 | |
762 sx = gdImageSX(src); | |
763 sy = gdImageSY(src); | |
764 | |
765 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | |
766 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
767 if (!ctx->force |
3878 | 768 && ctx->angle == 0 |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
769 && (ngx_uint_t) sx <= ctx->max_width |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
770 && (ngx_uint_t) sy <= ctx->max_height) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
771 { |
2788 | 772 gdImageDestroy(src); |
773 return ngx_http_image_asis(r, ctx); | |
774 } | |
775 | |
776 colors = gdImageColorsTotal(src); | |
3134 | 777 |
778 if (colors && conf->transparency) { | |
779 transparent = gdImageGetTransparent(src); | |
780 | |
781 if (transparent != -1) { | |
782 palette = colors; | |
783 red = gdImageRed(src, transparent); | |
784 green = gdImageGreen(src, transparent); | |
785 blue = gdImageBlue(src, transparent); | |
2788 | 786 |
3134 | 787 goto transparent; |
788 } | |
789 } | |
3117 | 790 |
3134 | 791 palette = 0; |
792 transparent = -1; | |
793 red = 0; | |
794 green = 0; | |
795 blue = 0; | |
796 | |
797 transparent: | |
798 | |
799 gdImageColorTransparent(src, -1); | |
3117 | 800 |
2788 | 801 dx = sx; |
802 dy = sy; | |
803 | |
804 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { | |
805 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
806 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
807 dy = dy * ctx->max_width / dx; |
2788 | 808 dy = dy ? dy : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
809 dx = ctx->max_width; |
2788 | 810 } |
811 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
812 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
813 dx = dx * ctx->max_height / dy; |
2788 | 814 dx = dx ? dx : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
815 dy = ctx->max_height; |
2788 | 816 } |
817 | |
818 resize = 1; | |
819 | |
3878 | 820 } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) { |
821 | |
822 resize = 0; | |
823 | |
2788 | 824 } else { /* NGX_HTTP_IMAGE_CROP */ |
825 | |
826 resize = 0; | |
827 | |
4601
084137d883ec
Image filter: compare aspect ratio more accurately during crop.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
828 if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) { |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
829 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
830 dy = dy * ctx->max_width / dx; |
2788 | 831 dy = dy ? dy : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
832 dx = ctx->max_width; |
2788 | 833 resize = 1; |
834 } | |
835 | |
836 } else { | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
837 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
838 dx = dx * ctx->max_height / dy; |
2788 | 839 dx = dx ? dx : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
840 dy = ctx->max_height; |
2788 | 841 resize = 1; |
842 } | |
843 } | |
844 } | |
845 | |
846 if (resize) { | |
3134 | 847 dst = ngx_http_image_new(r, dx, dy, palette); |
2788 | 848 if (dst == NULL) { |
849 gdImageDestroy(src); | |
850 return NULL; | |
851 } | |
852 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
853 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
854 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
855 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
856 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
857 |
2788 | 858 gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); |
859 | |
3134 | 860 if (colors) { |
861 gdImageTrueColorToPalette(dst, 1, 256); | |
862 } | |
863 | |
2788 | 864 gdImageDestroy(src); |
865 | |
866 } else { | |
867 dst = src; | |
868 } | |
869 | |
3878 | 870 if (ctx->angle) { |
871 src = dst; | |
872 | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
873 ax = (dx % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
874 ay = (dy % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
875 |
3878 | 876 switch (ctx->angle) { |
877 | |
878 case 90: | |
879 case 270: | |
880 dst = ngx_http_image_new(r, dy, dx, palette); | |
881 if (dst == NULL) { | |
882 gdImageDestroy(src); | |
883 return NULL; | |
884 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
885 if (ctx->angle == 90) { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
886 ox = dy / 2 + ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
887 oy = dx / 2 - ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
888 |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
889 } else { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
890 ox = dy / 2 - ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
891 oy = dx / 2 + ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
892 } |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
893 |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
894 gdImageCopyRotated(dst, src, ox, oy, 0, 0, |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
895 dx + ax, dy + ay, ctx->angle); |
3878 | 896 gdImageDestroy(src); |
3884
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
897 |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
898 t = dx; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
899 dx = dy; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
900 dy = t; |
3878 | 901 break; |
902 | |
903 case 180: | |
904 dst = ngx_http_image_new(r, dx, dy, palette); | |
905 if (dst == NULL) { | |
906 gdImageDestroy(src); | |
907 return NULL; | |
908 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
909 gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0, |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
910 dx + ax, dy + ay, ctx->angle); |
3878 | 911 gdImageDestroy(src); |
912 break; | |
913 } | |
914 } | |
915 | |
2788 | 916 if (conf->filter == NGX_HTTP_IMAGE_CROP) { |
917 | |
918 src = dst; | |
919 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
920 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
921 ox = dx - ctx->max_width; |
2788 | 922 |
923 } else { | |
924 ox = 0; | |
925 } | |
926 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
927 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
928 oy = dy - ctx->max_height; |
2788 | 929 |
930 } else { | |
931 oy = 0; | |
932 } | |
933 | |
934 if (ox || oy) { | |
935 | |
936 dst = ngx_http_image_new(r, dx - ox, dy - oy, colors); | |
937 | |
938 if (dst == NULL) { | |
939 gdImageDestroy(src); | |
940 return NULL; | |
941 } | |
942 | |
943 ox /= 2; | |
944 oy /= 2; | |
945 | |
946 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
947 "image crop: %d x %d @ %d x %d", | |
948 dx, dy, ox, oy); | |
949 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
950 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
951 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
952 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
953 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
954 |
2788 | 955 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); |
956 | |
3134 | 957 if (colors) { |
958 gdImageTrueColorToPalette(dst, 1, 256); | |
959 } | |
960 | |
2788 | 961 gdImageDestroy(src); |
962 } | |
963 } | |
964 | |
3117 | 965 if (transparent != -1 && colors) { |
966 gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); | |
967 } | |
2788 | 968 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
969 sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
970 if (sharpen > 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
971 gdImageSharpen(dst, sharpen); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
972 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
973 |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
974 gdImageInterlace(dst, (int) conf->interlace); |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
975 |
2788 | 976 out = ngx_http_image_out(r, ctx->type, dst, &size); |
977 | |
978 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
979 "image: %d x %d %d", sx, sy, colors); | |
980 | |
981 gdImageDestroy(dst); | |
982 ngx_pfree(r->pool, ctx->image); | |
983 | |
984 if (out == NULL) { | |
985 return NULL; | |
986 } | |
987 | |
988 cln = ngx_pool_cleanup_add(r->pool, 0); | |
989 if (cln == NULL) { | |
990 gdFree(out); | |
991 return NULL; | |
992 } | |
993 | |
994 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
995 if (b == NULL) { | |
996 gdFree(out); | |
997 return NULL; | |
998 } | |
999 | |
1000 cln->handler = ngx_http_image_cleanup; | |
1001 cln->data = out; | |
1002 | |
1003 b->pos = out; | |
1004 b->last = out + size; | |
1005 b->memory = 1; | |
1006 b->last_buf = 1; | |
1007 | |
1008 ngx_http_image_length(r, b); | |
1009 | |
1010 return b; | |
1011 } | |
1012 | |
1013 | |
1014 static gdImagePtr | |
1015 ngx_http_image_source(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
1016 { | |
1017 char *failed; | |
1018 gdImagePtr img; | |
1019 | |
1020 img = NULL; | |
1021 | |
1022 switch (ctx->type) { | |
1023 | |
1024 case NGX_HTTP_IMAGE_JPEG: | |
1025 img = gdImageCreateFromJpegPtr(ctx->length, ctx->image); | |
1026 failed = "gdImageCreateFromJpegPtr() failed"; | |
1027 break; | |
1028 | |
1029 case NGX_HTTP_IMAGE_GIF: | |
1030 img = gdImageCreateFromGifPtr(ctx->length, ctx->image); | |
1031 failed = "gdImageCreateFromGifPtr() failed"; | |
1032 break; | |
1033 | |
1034 case NGX_HTTP_IMAGE_PNG: | |
1035 img = gdImageCreateFromPngPtr(ctx->length, ctx->image); | |
1036 failed = "gdImageCreateFromPngPtr() failed"; | |
1037 break; | |
1038 | |
1039 default: | |
1040 failed = "unknown image type"; | |
1041 break; | |
1042 } | |
1043 | |
1044 if (img == NULL) { | |
1045 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1046 } | |
1047 | |
1048 return img; | |
1049 } | |
1050 | |
1051 | |
1052 static gdImagePtr | |
1053 ngx_http_image_new(ngx_http_request_t *r, int w, int h, int colors) | |
1054 { | |
1055 gdImagePtr img; | |
1056 | |
1057 if (colors == 0) { | |
1058 img = gdImageCreateTrueColor(w, h); | |
1059 | |
1060 if (img == NULL) { | |
1061 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1062 "gdImageCreateTrueColor() failed"); | |
1063 return NULL; | |
1064 } | |
1065 | |
1066 } else { | |
1067 img = gdImageCreate(w, h); | |
1068 | |
1069 if (img == NULL) { | |
1070 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1071 "gdImageCreate() failed"); | |
1072 return NULL; | |
1073 } | |
1074 } | |
1075 | |
1076 return img; | |
1077 } | |
1078 | |
1079 | |
1080 static u_char * | |
1081 ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, | |
1082 int *size) | |
1083 { | |
2848 | 1084 char *failed; |
1085 u_char *out; | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1086 ngx_int_t jq; |
2848 | 1087 ngx_http_image_filter_conf_t *conf; |
2788 | 1088 |
1089 out = NULL; | |
1090 | |
1091 switch (type) { | |
1092 | |
1093 case NGX_HTTP_IMAGE_JPEG: | |
2848 | 1094 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1095 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1096 jq = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1097 if (jq <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1098 return NULL; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1099 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1100 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1101 out = gdImageJpegPtr(img, size, jq); |
2788 | 1102 failed = "gdImageJpegPtr() failed"; |
1103 break; | |
1104 | |
1105 case NGX_HTTP_IMAGE_GIF: | |
1106 out = gdImageGifPtr(img, size); | |
1107 failed = "gdImageGifPtr() failed"; | |
1108 break; | |
1109 | |
1110 case NGX_HTTP_IMAGE_PNG: | |
1111 out = gdImagePngPtr(img, size); | |
1112 failed = "gdImagePngPtr() failed"; | |
1113 break; | |
1114 | |
1115 default: | |
1116 failed = "unknown image type"; | |
1117 break; | |
1118 } | |
1119 | |
1120 if (out == NULL) { | |
1121 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1122 } | |
1123 | |
1124 return out; | |
1125 } | |
1126 | |
1127 | |
1128 static void | |
1129 ngx_http_image_cleanup(void *data) | |
1130 { | |
1131 gdFree(data); | |
1132 } | |
1133 | |
1134 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1135 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1136 ngx_http_image_filter_get_value(ngx_http_request_t *r, |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1137 ngx_http_complex_value_t *cv, ngx_uint_t v) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1138 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1139 ngx_str_t val; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1140 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1141 if (cv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1142 return v; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1143 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1144 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1145 if (ngx_http_complex_value(r, cv, &val) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1146 return 0; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1147 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1148 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1149 return ngx_http_image_filter_value(&val); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1150 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1151 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1152 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1153 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1154 ngx_http_image_filter_value(ngx_str_t *value) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1155 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1156 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1157 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1158 if (value->len == 1 && value->data[0] == '-') { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1159 return (ngx_uint_t) -1; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1160 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1161 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1162 n = ngx_atoi(value->data, value->len); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1163 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1164 if (n > 0) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1165 return (ngx_uint_t) n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1166 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1167 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1168 return 0; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1169 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1170 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1171 |
2788 | 1172 static void * |
1173 ngx_http_image_filter_create_conf(ngx_conf_t *cf) | |
1174 { | |
1175 ngx_http_image_filter_conf_t *conf; | |
1176 | |
1177 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t)); | |
1178 if (conf == NULL) { | |
2912
c7d57b539248
return NULL instead of NGX_CONF_ERROR on a create conf failure
Igor Sysoev <igor@sysoev.ru>
parents:
2882
diff
changeset
|
1179 return NULL; |
2788 | 1180 } |
1181 | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1182 /* |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1183 * set by ngx_pcalloc(): |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1184 * |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1185 * conf->width = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1186 * conf->height = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1187 * conf->angle = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1188 * conf->wcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1189 * conf->hcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1190 * conf->acv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1191 * conf->jqcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1192 * conf->shcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1193 */ |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1194 |
2788 | 1195 conf->filter = NGX_CONF_UNSET_UINT; |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1196 conf->jpeg_quality = NGX_CONF_UNSET_UINT; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1197 conf->sharpen = NGX_CONF_UNSET_UINT; |
3134 | 1198 conf->transparency = NGX_CONF_UNSET; |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
1199 conf->interlace = NGX_CONF_UNSET; |
2788 | 1200 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
1201 | |
1202 return conf; | |
1203 } | |
1204 | |
1205 | |
1206 static char * | |
1207 ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
1208 { | |
1209 ngx_http_image_filter_conf_t *prev = parent; | |
1210 ngx_http_image_filter_conf_t *conf = child; | |
1211 | |
1212 if (conf->filter == NGX_CONF_UNSET_UINT) { | |
1213 | |
1214 if (prev->filter == NGX_CONF_UNSET_UINT) { | |
1215 conf->filter = NGX_HTTP_IMAGE_OFF; | |
1216 | |
1217 } else { | |
1218 conf->filter = prev->filter; | |
1219 conf->width = prev->width; | |
1220 conf->height = prev->height; | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1221 conf->angle = prev->angle; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1222 conf->wcv = prev->wcv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1223 conf->hcv = prev->hcv; |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1224 conf->acv = prev->acv; |
2788 | 1225 } |
1226 } | |
1227 | |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1228 if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) { |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1229 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1230 /* 75 is libjpeg default quality */ |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1231 ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75); |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1232 |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1233 if (conf->jqcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1234 conf->jqcv = prev->jqcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1235 } |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1236 } |
2848 | 1237 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1238 if (conf->sharpen == NGX_CONF_UNSET_UINT) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1239 ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1240 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1241 if (conf->shcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1242 conf->shcv = prev->shcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1243 } |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1244 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1245 |
3134 | 1246 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); |
1247 | |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
1248 ngx_conf_merge_value(conf->interlace, prev->interlace, 0); |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
1249 |
2788 | 1250 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1251 1 * 1024 * 1024); | |
1252 | |
1253 return NGX_CONF_OK; | |
1254 } | |
1255 | |
1256 | |
1257 static char * | |
1258 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1259 { | |
1260 ngx_http_image_filter_conf_t *imcf = conf; | |
1261 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1262 ngx_str_t *value; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1263 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1264 ngx_uint_t i; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1265 ngx_http_complex_value_t cv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1266 ngx_http_compile_complex_value_t ccv; |
2788 | 1267 |
1268 value = cf->args->elts; | |
1269 | |
1270 i = 1; | |
1271 | |
1272 if (cf->args->nelts == 2) { | |
1273 if (ngx_strcmp(value[i].data, "off") == 0) { | |
1274 imcf->filter = NGX_HTTP_IMAGE_OFF; | |
1275 | |
1276 } else if (ngx_strcmp(value[i].data, "test") == 0) { | |
1277 imcf->filter = NGX_HTTP_IMAGE_TEST; | |
1278 | |
1279 } else if (ngx_strcmp(value[i].data, "size") == 0) { | |
1280 imcf->filter = NGX_HTTP_IMAGE_SIZE; | |
1281 | |
1282 } else { | |
1283 goto failed; | |
1284 } | |
1285 | |
1286 return NGX_CONF_OK; | |
3878 | 1287 |
1288 } else if (cf->args->nelts == 3) { | |
1289 | |
1290 if (ngx_strcmp(value[i].data, "rotate") == 0) { | |
4308
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1291 if (imcf->filter != NGX_HTTP_IMAGE_RESIZE |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1292 && imcf->filter != NGX_HTTP_IMAGE_CROP) |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1293 { |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1294 imcf->filter = NGX_HTTP_IMAGE_ROTATE; |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1295 } |
3878 | 1296 |
1297 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1298 | |
1299 ccv.cf = cf; | |
1300 ccv.value = &value[++i]; | |
1301 ccv.complex_value = &cv; | |
1302 | |
1303 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1304 return NGX_CONF_ERROR; | |
1305 } | |
1306 | |
1307 if (cv.lengths == NULL) { | |
1308 n = ngx_http_image_filter_value(&value[i]); | |
1309 | |
1310 if (n != 90 && n != 180 && n != 270) { | |
1311 goto failed; | |
1312 } | |
1313 | |
1314 imcf->angle = (ngx_uint_t) n; | |
1315 | |
1316 } else { | |
1317 imcf->acv = ngx_palloc(cf->pool, | |
1318 sizeof(ngx_http_complex_value_t)); | |
1319 if (imcf->acv == NULL) { | |
1320 return NGX_CONF_ERROR; | |
1321 } | |
1322 | |
1323 *imcf->acv = cv; | |
1324 } | |
1325 | |
1326 return NGX_CONF_OK; | |
1327 | |
1328 } else { | |
1329 goto failed; | |
1330 } | |
2788 | 1331 } |
1332 | |
1333 if (ngx_strcmp(value[i].data, "resize") == 0) { | |
1334 imcf->filter = NGX_HTTP_IMAGE_RESIZE; | |
1335 | |
1336 } else if (ngx_strcmp(value[i].data, "crop") == 0) { | |
1337 imcf->filter = NGX_HTTP_IMAGE_CROP; | |
1338 | |
1339 } else { | |
1340 goto failed; | |
1341 } | |
1342 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1343 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1344 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1345 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1346 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1347 ccv.complex_value = &cv; |
2788 | 1348 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1349 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1350 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1351 } |
2788 | 1352 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1353 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1354 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1355 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1356 if (n == 0) { |
2788 | 1357 goto failed; |
1358 } | |
1359 | |
1360 imcf->width = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1361 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1362 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1363 imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1364 if (imcf->wcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1365 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1366 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1367 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1368 *imcf->wcv = cv; |
2788 | 1369 } |
1370 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1371 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1372 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1373 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1374 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1375 ccv.complex_value = &cv; |
2788 | 1376 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1377 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1378 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1379 } |
2788 | 1380 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1381 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1382 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1383 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1384 if (n == 0) { |
2788 | 1385 goto failed; |
1386 } | |
1387 | |
1388 imcf->height = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1389 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1390 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1391 imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1392 if (imcf->hcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1393 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1394 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1395 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1396 *imcf->hcv = cv; |
2788 | 1397 } |
1398 | |
1399 return NGX_CONF_OK; | |
1400 | |
1401 failed: | |
1402 | |
1403 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", | |
1404 &value[i]); | |
1405 | |
1406 return NGX_CONF_ERROR; | |
1407 } | |
1408 | |
1409 | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1410 static char * |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1411 ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd, |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1412 void *conf) |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1413 { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1414 ngx_http_image_filter_conf_t *imcf = conf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1415 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1416 ngx_str_t *value; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1417 ngx_int_t n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1418 ngx_http_complex_value_t cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1419 ngx_http_compile_complex_value_t ccv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1420 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1421 value = cf->args->elts; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1422 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1423 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1424 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1425 ccv.cf = cf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1426 ccv.value = &value[1]; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1427 ccv.complex_value = &cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1428 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1429 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1430 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1431 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1432 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1433 if (cv.lengths == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1434 n = ngx_http_image_filter_value(&value[1]); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1435 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1436 if (n <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1437 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1438 "invalid value \"%V\"", &value[1]); |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1439 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1440 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1441 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1442 imcf->jpeg_quality = (ngx_uint_t) n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1443 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1444 } else { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1445 imcf->jqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1446 if (imcf->jqcv == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1447 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1448 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1449 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1450 *imcf->jqcv = cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1451 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1452 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1453 return NGX_CONF_OK; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1454 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1455 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1456 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1457 static char * |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1458 ngx_http_image_filter_sharpen(ngx_conf_t *cf, ngx_command_t *cmd, |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1459 void *conf) |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1460 { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1461 ngx_http_image_filter_conf_t *imcf = conf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1462 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1463 ngx_str_t *value; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1464 ngx_int_t n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1465 ngx_http_complex_value_t cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1466 ngx_http_compile_complex_value_t ccv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1467 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1468 value = cf->args->elts; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1469 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1470 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1471 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1472 ccv.cf = cf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1473 ccv.value = &value[1]; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1474 ccv.complex_value = &cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1475 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1476 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1477 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1478 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1479 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1480 if (cv.lengths == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1481 n = ngx_http_image_filter_value(&value[1]); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1482 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1483 if (n < 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1484 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1485 "invalid value \"%V\"", &value[1]); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1486 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1487 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1488 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1489 imcf->sharpen = (ngx_uint_t) n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1490 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1491 } else { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1492 imcf->shcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1493 if (imcf->shcv == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1494 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1495 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1496 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1497 *imcf->shcv = cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1498 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1499 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1500 return NGX_CONF_OK; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1501 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1502 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1503 |
2788 | 1504 static ngx_int_t |
1505 ngx_http_image_filter_init(ngx_conf_t *cf) | |
1506 { | |
1507 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
1508 ngx_http_top_header_filter = ngx_http_image_header_filter; | |
1509 | |
1510 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
1511 ngx_http_top_body_filter = ngx_http_image_body_filter; | |
1512 | |
1513 return NGX_OK; | |
1514 } |