Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_image_filter_module.c @ 5110:0bbdd966a383
Request body: next upstream fix.
After introduction of chunked request body handling in 1.3.9 (r4931),
r->request_body->bufs buffers have b->start pointing to original buffer
start (and b->pos pointing to real data of this particular buffer).
While this is ok as per se, it caused bad things (usually original request
headers included before the request body) after reinit of the request
chain in ngx_http_upstream_reinit() while sending the request to a next
upstream server (which used to do b->pos = b->start for each buffer
in the request chain).
Patch by Piotr Sikora.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 14 Mar 2013 12:28:53 +0000 |
parents | 5889bc5f7a65 |
children | af155fc41deb |
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 | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1172 /* |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1173 * set by ngx_pcalloc(): |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1174 * |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1175 * conf->width = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1176 * conf->height = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1177 * conf->angle = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1178 * conf->wcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1179 * conf->hcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1180 * conf->acv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1181 * conf->jqcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1182 * conf->shcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1183 */ |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1184 |
2788 | 1185 conf->filter = NGX_CONF_UNSET_UINT; |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1186 conf->jpeg_quality = NGX_CONF_UNSET_UINT; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1187 conf->sharpen = NGX_CONF_UNSET_UINT; |
3134 | 1188 conf->transparency = NGX_CONF_UNSET; |
2788 | 1189 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
1190 | |
1191 return conf; | |
1192 } | |
1193 | |
1194 | |
1195 static char * | |
1196 ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
1197 { | |
1198 ngx_http_image_filter_conf_t *prev = parent; | |
1199 ngx_http_image_filter_conf_t *conf = child; | |
1200 | |
1201 if (conf->filter == NGX_CONF_UNSET_UINT) { | |
1202 | |
1203 if (prev->filter == NGX_CONF_UNSET_UINT) { | |
1204 conf->filter = NGX_HTTP_IMAGE_OFF; | |
1205 | |
1206 } else { | |
1207 conf->filter = prev->filter; | |
1208 conf->width = prev->width; | |
1209 conf->height = prev->height; | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1210 conf->angle = prev->angle; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1211 conf->wcv = prev->wcv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1212 conf->hcv = prev->hcv; |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1213 conf->acv = prev->acv; |
2788 | 1214 } |
1215 } | |
1216 | |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1217 if (conf->jpeg_quality == NGX_CONF_UNSET_UINT) { |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1218 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1219 /* 75 is libjpeg default quality */ |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1220 ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75); |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1221 |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1222 if (conf->jqcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1223 conf->jqcv = prev->jqcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1224 } |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1225 } |
2848 | 1226 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1227 if (conf->sharpen == NGX_CONF_UNSET_UINT) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1228 ngx_conf_merge_uint_value(conf->sharpen, prev->sharpen, 0); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1229 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1230 if (conf->shcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1231 conf->shcv = prev->shcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1232 } |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1233 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1234 |
3134 | 1235 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); |
1236 | |
2788 | 1237 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1238 1 * 1024 * 1024); | |
1239 | |
1240 return NGX_CONF_OK; | |
1241 } | |
1242 | |
1243 | |
1244 static char * | |
1245 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1246 { | |
1247 ngx_http_image_filter_conf_t *imcf = conf; | |
1248 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1249 ngx_str_t *value; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1250 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1251 ngx_uint_t i; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1252 ngx_http_complex_value_t cv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1253 ngx_http_compile_complex_value_t ccv; |
2788 | 1254 |
1255 value = cf->args->elts; | |
1256 | |
1257 i = 1; | |
1258 | |
1259 if (cf->args->nelts == 2) { | |
1260 if (ngx_strcmp(value[i].data, "off") == 0) { | |
1261 imcf->filter = NGX_HTTP_IMAGE_OFF; | |
1262 | |
1263 } else if (ngx_strcmp(value[i].data, "test") == 0) { | |
1264 imcf->filter = NGX_HTTP_IMAGE_TEST; | |
1265 | |
1266 } else if (ngx_strcmp(value[i].data, "size") == 0) { | |
1267 imcf->filter = NGX_HTTP_IMAGE_SIZE; | |
1268 | |
1269 } else { | |
1270 goto failed; | |
1271 } | |
1272 | |
1273 return NGX_CONF_OK; | |
3878 | 1274 |
1275 } else if (cf->args->nelts == 3) { | |
1276 | |
1277 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
|
1278 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
|
1279 && 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
|
1280 { |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1281 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
|
1282 } |
3878 | 1283 |
1284 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1285 | |
1286 ccv.cf = cf; | |
1287 ccv.value = &value[++i]; | |
1288 ccv.complex_value = &cv; | |
1289 | |
1290 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1291 return NGX_CONF_ERROR; | |
1292 } | |
1293 | |
1294 if (cv.lengths == NULL) { | |
1295 n = ngx_http_image_filter_value(&value[i]); | |
1296 | |
1297 if (n != 90 && n != 180 && n != 270) { | |
1298 goto failed; | |
1299 } | |
1300 | |
1301 imcf->angle = (ngx_uint_t) n; | |
1302 | |
1303 } else { | |
1304 imcf->acv = ngx_palloc(cf->pool, | |
1305 sizeof(ngx_http_complex_value_t)); | |
1306 if (imcf->acv == NULL) { | |
1307 return NGX_CONF_ERROR; | |
1308 } | |
1309 | |
1310 *imcf->acv = cv; | |
1311 } | |
1312 | |
1313 return NGX_CONF_OK; | |
1314 | |
1315 } else { | |
1316 goto failed; | |
1317 } | |
2788 | 1318 } |
1319 | |
1320 if (ngx_strcmp(value[i].data, "resize") == 0) { | |
1321 imcf->filter = NGX_HTTP_IMAGE_RESIZE; | |
1322 | |
1323 } else if (ngx_strcmp(value[i].data, "crop") == 0) { | |
1324 imcf->filter = NGX_HTTP_IMAGE_CROP; | |
1325 | |
1326 } else { | |
1327 goto failed; | |
1328 } | |
1329 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1330 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
|
1331 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1332 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1333 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1334 ccv.complex_value = &cv; |
2788 | 1335 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1336 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1337 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1338 } |
2788 | 1339 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1340 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1341 n = ngx_http_image_filter_value(&value[i]); |
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 if (n == 0) { |
2788 | 1344 goto failed; |
1345 } | |
1346 | |
1347 imcf->width = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1348 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1349 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1350 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
|
1351 if (imcf->wcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1352 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1353 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1354 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1355 *imcf->wcv = cv; |
2788 | 1356 } |
1357 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1358 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
|
1359 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1360 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1361 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1362 ccv.complex_value = &cv; |
2788 | 1363 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1364 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1365 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1366 } |
2788 | 1367 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1368 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1369 n = ngx_http_image_filter_value(&value[i]); |
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 if (n == 0) { |
2788 | 1372 goto failed; |
1373 } | |
1374 | |
1375 imcf->height = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1376 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1377 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1378 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
|
1379 if (imcf->hcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1380 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1381 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1382 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1383 *imcf->hcv = cv; |
2788 | 1384 } |
1385 | |
1386 return NGX_CONF_OK; | |
1387 | |
1388 failed: | |
1389 | |
1390 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", | |
1391 &value[i]); | |
1392 | |
1393 return NGX_CONF_ERROR; | |
1394 } | |
1395 | |
1396 | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1397 static char * |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1398 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
|
1399 void *conf) |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1400 { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1401 ngx_http_image_filter_conf_t *imcf = conf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1402 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1403 ngx_str_t *value; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1404 ngx_int_t n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1405 ngx_http_complex_value_t cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1406 ngx_http_compile_complex_value_t ccv; |
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 value = cf->args->elts; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1409 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1410 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
|
1411 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1412 ccv.cf = cf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1413 ccv.value = &value[1]; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1414 ccv.complex_value = &cv; |
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 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
|
1417 return NGX_CONF_ERROR; |
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 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1420 if (cv.lengths == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1421 n = ngx_http_image_filter_value(&value[1]); |
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 if (n <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1424 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1425 "invalid value \"%V\"", &value[1]); |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1426 return NGX_CONF_ERROR; |
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 imcf->jpeg_quality = (ngx_uint_t) n; |
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 } else { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1432 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
|
1433 if (imcf->jqcv == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1434 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1435 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1436 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1437 *imcf->jqcv = cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1438 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1439 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1440 return NGX_CONF_OK; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1441 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1442 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1443 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1444 static char * |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1445 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
|
1446 void *conf) |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1447 { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1448 ngx_http_image_filter_conf_t *imcf = conf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1449 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1450 ngx_str_t *value; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1451 ngx_int_t n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1452 ngx_http_complex_value_t cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1453 ngx_http_compile_complex_value_t ccv; |
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 value = cf->args->elts; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1456 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1457 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
|
1458 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1459 ccv.cf = cf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1460 ccv.value = &value[1]; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1461 ccv.complex_value = &cv; |
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 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1464 return NGX_CONF_ERROR; |
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 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1467 if (cv.lengths == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1468 n = ngx_http_image_filter_value(&value[1]); |
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 if (n < 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1471 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1472 "invalid value \"%V\"", &value[1]); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1473 return NGX_CONF_ERROR; |
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 imcf->sharpen = (ngx_uint_t) n; |
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 } else { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1479 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
|
1480 if (imcf->shcv == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1481 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1482 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1483 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1484 *imcf->shcv = cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1485 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1486 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1487 return NGX_CONF_OK; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1488 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1489 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1490 |
2788 | 1491 static ngx_int_t |
1492 ngx_http_image_filter_init(ngx_conf_t *cf) | |
1493 { | |
1494 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
1495 ngx_http_top_header_filter = ngx_http_image_header_filter; | |
1496 | |
1497 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
1498 ngx_http_top_body_filter = ngx_http_image_body_filter; | |
1499 | |
1500 return NGX_OK; | |
1501 } |