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