Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_image_filter_module.c @ 4458:2d4ff8bd5649
Limit conn: returned to the old behavior of using the first actual limit on
the way.
It was unintentionally changed in r4272, so that it could only limit the first
location where the processing of the request has reached PREACCESS phase.
author | Valentin Bartenev <vbart@nginx.com> |
---|---|
date | Fri, 10 Feb 2012 10:48:58 +0000 |
parents | d620f497c50f |
children | 084137d883ec |
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 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
820 if ((ngx_uint_t) (dx * 100 / dy) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
821 < ctx->max_width * 100 / ctx->max_height) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
822 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
823 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
824 dy = dy * ctx->max_width / dx; |
2788 | 825 dy = dy ? dy : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
826 dx = ctx->max_width; |
2788 | 827 resize = 1; |
828 } | |
829 | |
830 } else { | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
831 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
832 dx = dx * ctx->max_height / dy; |
2788 | 833 dx = dx ? dx : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
834 dy = ctx->max_height; |
2788 | 835 resize = 1; |
836 } | |
837 } | |
838 } | |
839 | |
840 if (resize) { | |
3134 | 841 dst = ngx_http_image_new(r, dx, dy, palette); |
2788 | 842 if (dst == NULL) { |
843 gdImageDestroy(src); | |
844 return NULL; | |
845 } | |
846 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
847 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
848 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
849 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
850 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
851 |
2788 | 852 gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); |
853 | |
3134 | 854 if (colors) { |
855 gdImageTrueColorToPalette(dst, 1, 256); | |
856 } | |
857 | |
2788 | 858 gdImageDestroy(src); |
859 | |
860 } else { | |
861 dst = src; | |
862 } | |
863 | |
3878 | 864 if (ctx->angle) { |
865 src = dst; | |
866 | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
867 ax = (dx % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
868 ay = (dy % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
869 |
3878 | 870 switch (ctx->angle) { |
871 | |
872 case 90: | |
873 case 270: | |
874 dst = ngx_http_image_new(r, dy, dx, palette); | |
875 if (dst == NULL) { | |
876 gdImageDestroy(src); | |
877 return NULL; | |
878 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
879 if (ctx->angle == 90) { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
880 ox = dy / 2 + ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
881 oy = dx / 2 - ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
882 |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
883 } else { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
884 ox = dy / 2 - ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
885 oy = dx / 2 + ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
886 } |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
887 |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
888 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
|
889 dx + ax, dy + ay, ctx->angle); |
3878 | 890 gdImageDestroy(src); |
3884
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
891 |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
892 t = dx; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
893 dx = dy; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
894 dy = t; |
3878 | 895 break; |
896 | |
897 case 180: | |
898 dst = ngx_http_image_new(r, dx, dy, palette); | |
899 if (dst == NULL) { | |
900 gdImageDestroy(src); | |
901 return NULL; | |
902 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
903 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
|
904 dx + ax, dy + ay, ctx->angle); |
3878 | 905 gdImageDestroy(src); |
906 break; | |
907 } | |
908 } | |
909 | |
2788 | 910 if (conf->filter == NGX_HTTP_IMAGE_CROP) { |
911 | |
912 src = dst; | |
913 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
914 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
915 ox = dx - ctx->max_width; |
2788 | 916 |
917 } else { | |
918 ox = 0; | |
919 } | |
920 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
921 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
922 oy = dy - ctx->max_height; |
2788 | 923 |
924 } else { | |
925 oy = 0; | |
926 } | |
927 | |
928 if (ox || oy) { | |
929 | |
930 dst = ngx_http_image_new(r, dx - ox, dy - oy, colors); | |
931 | |
932 if (dst == NULL) { | |
933 gdImageDestroy(src); | |
934 return NULL; | |
935 } | |
936 | |
937 ox /= 2; | |
938 oy /= 2; | |
939 | |
940 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
941 "image crop: %d x %d @ %d x %d", | |
942 dx, dy, ox, oy); | |
943 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
944 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
945 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
946 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
947 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
948 |
2788 | 949 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); |
950 | |
3134 | 951 if (colors) { |
952 gdImageTrueColorToPalette(dst, 1, 256); | |
953 } | |
954 | |
2788 | 955 gdImageDestroy(src); |
956 } | |
957 } | |
958 | |
3117 | 959 if (transparent != -1 && colors) { |
960 gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); | |
961 } | |
2788 | 962 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
963 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
|
964 if (sharpen > 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
965 gdImageSharpen(dst, sharpen); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
966 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
967 |
2788 | 968 out = ngx_http_image_out(r, ctx->type, dst, &size); |
969 | |
970 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
971 "image: %d x %d %d", sx, sy, colors); | |
972 | |
973 gdImageDestroy(dst); | |
974 ngx_pfree(r->pool, ctx->image); | |
975 | |
976 if (out == NULL) { | |
977 return NULL; | |
978 } | |
979 | |
980 cln = ngx_pool_cleanup_add(r->pool, 0); | |
981 if (cln == NULL) { | |
982 gdFree(out); | |
983 return NULL; | |
984 } | |
985 | |
986 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
987 if (b == NULL) { | |
988 gdFree(out); | |
989 return NULL; | |
990 } | |
991 | |
992 cln->handler = ngx_http_image_cleanup; | |
993 cln->data = out; | |
994 | |
995 b->pos = out; | |
996 b->last = out + size; | |
997 b->memory = 1; | |
998 b->last_buf = 1; | |
999 | |
1000 ngx_http_image_length(r, b); | |
1001 | |
1002 return b; | |
1003 } | |
1004 | |
1005 | |
1006 static gdImagePtr | |
1007 ngx_http_image_source(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
1008 { | |
1009 char *failed; | |
1010 gdImagePtr img; | |
1011 | |
1012 img = NULL; | |
1013 | |
1014 switch (ctx->type) { | |
1015 | |
1016 case NGX_HTTP_IMAGE_JPEG: | |
1017 img = gdImageCreateFromJpegPtr(ctx->length, ctx->image); | |
1018 failed = "gdImageCreateFromJpegPtr() failed"; | |
1019 break; | |
1020 | |
1021 case NGX_HTTP_IMAGE_GIF: | |
1022 img = gdImageCreateFromGifPtr(ctx->length, ctx->image); | |
1023 failed = "gdImageCreateFromGifPtr() failed"; | |
1024 break; | |
1025 | |
1026 case NGX_HTTP_IMAGE_PNG: | |
1027 img = gdImageCreateFromPngPtr(ctx->length, ctx->image); | |
1028 failed = "gdImageCreateFromPngPtr() failed"; | |
1029 break; | |
1030 | |
1031 default: | |
1032 failed = "unknown image type"; | |
1033 break; | |
1034 } | |
1035 | |
1036 if (img == NULL) { | |
1037 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1038 } | |
1039 | |
1040 return img; | |
1041 } | |
1042 | |
1043 | |
1044 static gdImagePtr | |
1045 ngx_http_image_new(ngx_http_request_t *r, int w, int h, int colors) | |
1046 { | |
1047 gdImagePtr img; | |
1048 | |
1049 if (colors == 0) { | |
1050 img = gdImageCreateTrueColor(w, h); | |
1051 | |
1052 if (img == NULL) { | |
1053 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1054 "gdImageCreateTrueColor() failed"); | |
1055 return NULL; | |
1056 } | |
1057 | |
1058 } else { | |
1059 img = gdImageCreate(w, h); | |
1060 | |
1061 if (img == NULL) { | |
1062 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1063 "gdImageCreate() failed"); | |
1064 return NULL; | |
1065 } | |
1066 } | |
1067 | |
1068 return img; | |
1069 } | |
1070 | |
1071 | |
1072 static u_char * | |
1073 ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, | |
1074 int *size) | |
1075 { | |
2848 | 1076 char *failed; |
1077 u_char *out; | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1078 ngx_int_t jq; |
2848 | 1079 ngx_http_image_filter_conf_t *conf; |
2788 | 1080 |
1081 out = NULL; | |
1082 | |
1083 switch (type) { | |
1084 | |
1085 case NGX_HTTP_IMAGE_JPEG: | |
2848 | 1086 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
|
1087 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1088 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
|
1089 if (jq <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1090 return NULL; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1091 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1092 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1093 out = gdImageJpegPtr(img, size, jq); |
2788 | 1094 failed = "gdImageJpegPtr() failed"; |
1095 break; | |
1096 | |
1097 case NGX_HTTP_IMAGE_GIF: | |
1098 out = gdImageGifPtr(img, size); | |
1099 failed = "gdImageGifPtr() failed"; | |
1100 break; | |
1101 | |
1102 case NGX_HTTP_IMAGE_PNG: | |
1103 out = gdImagePngPtr(img, size); | |
1104 failed = "gdImagePngPtr() failed"; | |
1105 break; | |
1106 | |
1107 default: | |
1108 failed = "unknown image type"; | |
1109 break; | |
1110 } | |
1111 | |
1112 if (out == NULL) { | |
1113 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1114 } | |
1115 | |
1116 return out; | |
1117 } | |
1118 | |
1119 | |
1120 static void | |
1121 ngx_http_image_cleanup(void *data) | |
1122 { | |
1123 gdFree(data); | |
1124 } | |
1125 | |
1126 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1127 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1128 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
|
1129 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
|
1130 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1131 ngx_str_t val; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1132 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1133 if (cv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1134 return v; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1135 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1136 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1137 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
|
1138 return 0; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1139 } |
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 return ngx_http_image_filter_value(&val); |
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 |
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 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1146 ngx_http_image_filter_value(ngx_str_t *value) |
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 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1149 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1150 if (value->len == 1 && value->data[0] == '-') { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1151 return (ngx_uint_t) -1; |
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 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1154 n = ngx_atoi(value->data, value->len); |
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 if (n > 0) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1157 return (ngx_uint_t) n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1158 } |
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 return 0; |
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 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1163 |
2788 | 1164 static void * |
1165 ngx_http_image_filter_create_conf(ngx_conf_t *cf) | |
1166 { | |
1167 ngx_http_image_filter_conf_t *conf; | |
1168 | |
1169 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t)); | |
1170 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
|
1171 return NULL; |
2788 | 1172 } |
1173 | |
1174 conf->filter = NGX_CONF_UNSET_UINT; | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1175 conf->jpeg_quality = NGX_CONF_UNSET_UINT; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1176 conf->sharpen = NGX_CONF_UNSET_UINT; |
3878 | 1177 conf->angle = NGX_CONF_UNSET_UINT; |
3134 | 1178 conf->transparency = NGX_CONF_UNSET; |
2788 | 1179 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
1180 | |
1181 return conf; | |
1182 } | |
1183 | |
1184 | |
1185 static char * | |
1186 ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
1187 { | |
1188 ngx_http_image_filter_conf_t *prev = parent; | |
1189 ngx_http_image_filter_conf_t *conf = child; | |
1190 | |
1191 if (conf->filter == NGX_CONF_UNSET_UINT) { | |
1192 | |
1193 if (prev->filter == NGX_CONF_UNSET_UINT) { | |
1194 conf->filter = NGX_HTTP_IMAGE_OFF; | |
1195 | |
1196 } else { | |
1197 conf->filter = prev->filter; | |
1198 conf->width = prev->width; | |
1199 conf->height = prev->height; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1200 conf->wcv = prev->wcv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1201 conf->hcv = prev->hcv; |
2788 | 1202 } |
1203 } | |
1204 | |
2848 | 1205 /* 75 is libjpeg default quality */ |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1206 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
|
1207 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1208 if (conf->jqcv == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1209 conf->jqcv = prev->jqcv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1210 } |
2848 | 1211 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1212 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
|
1213 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1214 if (conf->shcv == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1215 conf->shcv = prev->shcv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1216 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1217 |
3878 | 1218 ngx_conf_merge_uint_value(conf->angle, prev->angle, 0); |
1219 if (conf->acv == NULL) { | |
1220 conf->acv = prev->acv; | |
1221 } | |
1222 | |
3134 | 1223 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); |
1224 | |
2788 | 1225 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1226 1 * 1024 * 1024); | |
1227 | |
1228 return NGX_CONF_OK; | |
1229 } | |
1230 | |
1231 | |
1232 static char * | |
1233 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1234 { | |
1235 ngx_http_image_filter_conf_t *imcf = conf; | |
1236 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1237 ngx_str_t *value; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1238 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1239 ngx_uint_t i; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1240 ngx_http_complex_value_t cv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1241 ngx_http_compile_complex_value_t ccv; |
2788 | 1242 |
1243 value = cf->args->elts; | |
1244 | |
1245 i = 1; | |
1246 | |
1247 if (cf->args->nelts == 2) { | |
1248 if (ngx_strcmp(value[i].data, "off") == 0) { | |
1249 imcf->filter = NGX_HTTP_IMAGE_OFF; | |
1250 | |
1251 } else if (ngx_strcmp(value[i].data, "test") == 0) { | |
1252 imcf->filter = NGX_HTTP_IMAGE_TEST; | |
1253 | |
1254 } else if (ngx_strcmp(value[i].data, "size") == 0) { | |
1255 imcf->filter = NGX_HTTP_IMAGE_SIZE; | |
1256 | |
1257 } else { | |
1258 goto failed; | |
1259 } | |
1260 | |
1261 return NGX_CONF_OK; | |
3878 | 1262 |
1263 } else if (cf->args->nelts == 3) { | |
1264 | |
1265 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
|
1266 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
|
1267 && 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
|
1268 { |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1269 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
|
1270 } |
3878 | 1271 |
1272 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1273 | |
1274 ccv.cf = cf; | |
1275 ccv.value = &value[++i]; | |
1276 ccv.complex_value = &cv; | |
1277 | |
1278 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1279 return NGX_CONF_ERROR; | |
1280 } | |
1281 | |
1282 if (cv.lengths == NULL) { | |
1283 n = ngx_http_image_filter_value(&value[i]); | |
1284 | |
1285 if (n != 90 && n != 180 && n != 270) { | |
1286 goto failed; | |
1287 } | |
1288 | |
1289 imcf->angle = (ngx_uint_t) n; | |
1290 | |
1291 } else { | |
1292 imcf->acv = ngx_palloc(cf->pool, | |
1293 sizeof(ngx_http_complex_value_t)); | |
1294 if (imcf->acv == NULL) { | |
1295 return NGX_CONF_ERROR; | |
1296 } | |
1297 | |
1298 *imcf->acv = cv; | |
1299 } | |
1300 | |
1301 return NGX_CONF_OK; | |
1302 | |
1303 } else { | |
1304 goto failed; | |
1305 } | |
2788 | 1306 } |
1307 | |
1308 if (ngx_strcmp(value[i].data, "resize") == 0) { | |
1309 imcf->filter = NGX_HTTP_IMAGE_RESIZE; | |
1310 | |
1311 } else if (ngx_strcmp(value[i].data, "crop") == 0) { | |
1312 imcf->filter = NGX_HTTP_IMAGE_CROP; | |
1313 | |
1314 } else { | |
1315 goto failed; | |
1316 } | |
1317 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1318 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
|
1319 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1320 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1321 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1322 ccv.complex_value = &cv; |
2788 | 1323 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1324 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1325 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1326 } |
2788 | 1327 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1328 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1329 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1330 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1331 if (n == 0) { |
2788 | 1332 goto failed; |
1333 } | |
1334 | |
1335 imcf->width = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1336 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1337 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1338 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
|
1339 if (imcf->wcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1340 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1341 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1342 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1343 *imcf->wcv = cv; |
2788 | 1344 } |
1345 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1346 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
|
1347 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1348 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1349 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1350 ccv.complex_value = &cv; |
2788 | 1351 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1352 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1353 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1354 } |
2788 | 1355 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1356 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1357 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1358 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1359 if (n == 0) { |
2788 | 1360 goto failed; |
1361 } | |
1362 | |
1363 imcf->height = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1364 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1365 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1366 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
|
1367 if (imcf->hcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1368 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1369 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1370 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1371 *imcf->hcv = cv; |
2788 | 1372 } |
1373 | |
1374 return NGX_CONF_OK; | |
1375 | |
1376 failed: | |
1377 | |
1378 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", | |
1379 &value[i]); | |
1380 | |
1381 return NGX_CONF_ERROR; | |
1382 } | |
1383 | |
1384 | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1385 static char * |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1386 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
|
1387 void *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_http_image_filter_conf_t *imcf = conf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1390 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1391 ngx_str_t *value; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1392 ngx_int_t n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1393 ngx_http_complex_value_t cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1394 ngx_http_compile_complex_value_t ccv; |
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 value = cf->args->elts; |
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 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
|
1399 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1400 ccv.cf = cf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1401 ccv.value = &value[1]; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1402 ccv.complex_value = &cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1403 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1404 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
|
1405 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1406 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1407 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1408 if (cv.lengths == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1409 n = ngx_http_image_filter_value(&value[1]); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1410 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1411 if (n <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1412 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1413 "invalid value \"%V\"", &value[1]); |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1414 return NGX_CONF_ERROR; |
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 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1417 imcf->jpeg_quality = (ngx_uint_t) n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1418 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1419 } else { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1420 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
|
1421 if (imcf->jqcv == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1422 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1423 } |
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 *imcf->jqcv = cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1426 } |
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 return NGX_CONF_OK; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1429 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1430 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1431 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1432 static char * |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1433 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
|
1434 void *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_http_image_filter_conf_t *imcf = conf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1437 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1438 ngx_str_t *value; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1439 ngx_int_t n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1440 ngx_http_complex_value_t cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1441 ngx_http_compile_complex_value_t ccv; |
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 value = cf->args->elts; |
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 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
|
1446 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1447 ccv.cf = cf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1448 ccv.value = &value[1]; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1449 ccv.complex_value = &cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1450 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1451 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1452 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1453 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1454 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1455 if (cv.lengths == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1456 n = ngx_http_image_filter_value(&value[1]); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1457 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1458 if (n < 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1459 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1460 "invalid value \"%V\"", &value[1]); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1461 return NGX_CONF_ERROR; |
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 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1464 imcf->sharpen = (ngx_uint_t) n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1465 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1466 } else { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1467 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
|
1468 if (imcf->shcv == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1469 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1470 } |
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 *imcf->shcv = cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1473 } |
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 return NGX_CONF_OK; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1476 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1477 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1478 |
2788 | 1479 static ngx_int_t |
1480 ngx_http_image_filter_init(ngx_conf_t *cf) | |
1481 { | |
1482 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
1483 ngx_http_top_header_filter = ngx_http_image_header_filter; | |
1484 | |
1485 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
1486 ngx_http_top_body_filter = ngx_http_image_body_filter; | |
1487 | |
1488 return NGX_OK; | |
1489 } |