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