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