Mercurial > hg > nginx
annotate src/http/modules/ngx_http_image_filter_module.c @ 5358:670ceaba03d8
Win32: Open Watcom C compatibility fixes.
Precompiled headers are disabled as they lead to internal compiler errors
with long configure lines. Couple of false positive warnings silenced.
Various win32 typedefs are adjusted to work with Open Watcom C 1.9 headers.
With this patch, it's now again possible to compile nginx using owc386,
with options we normally compile on win32 minus ipv6 and ssl.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 04 Sep 2013 20:48:22 +0400 |
parents | 317e0893a1e6 |
children | 2cfc095a607a |
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; | |
5315
31932b5464f0
Image filter: use "application/json" MIME type for JSON output.
Valentin Bartenev <vbart@nginx.com>
parents:
5118
diff
changeset
|
575 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
|
576 r->headers_out.content_type_lowcase = NULL; |
2788 | 577 |
578 if (ctx == NULL) { | |
579 b->pos = (u_char *) "{}" CRLF; | |
580 b->last = b->pos + sizeof("{}" CRLF) - 1; | |
581 | |
582 ngx_http_image_length(r, b); | |
583 | |
584 return b; | |
585 } | |
586 | |
587 len = sizeof("{ \"img\" : " | |
588 "{ \"width\": , \"height\": , \"type\": \"jpeg\" } }" CRLF) - 1 | |
589 + 2 * NGX_SIZE_T_LEN; | |
590 | |
591 b->pos = ngx_pnalloc(r->pool, len); | |
592 if (b->pos == NULL) { | |
593 return NULL; | |
594 } | |
595 | |
596 b->last = ngx_sprintf(b->pos, | |
597 "{ \"img\" : " | |
598 "{ \"width\": %uz," | |
599 " \"height\": %uz," | |
600 " \"type\": \"%s\" } }" CRLF, | |
601 ctx->width, ctx->height, | |
602 ngx_http_image_types[ctx->type - 1].data + 6); | |
603 | |
604 ngx_http_image_length(r, b); | |
605 | |
606 return b; | |
607 } | |
608 | |
609 | |
610 static ngx_buf_t * | |
611 ngx_http_image_asis(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
612 { | |
613 ngx_buf_t *b; | |
614 | |
615 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
616 if (b == NULL) { | |
617 return NULL; | |
618 } | |
619 | |
620 b->pos = ctx->image; | |
621 b->last = ctx->last; | |
622 b->memory = 1; | |
623 b->last_buf = 1; | |
624 | |
625 ngx_http_image_length(r, b); | |
626 | |
627 return b; | |
628 } | |
629 | |
630 | |
631 static void | |
632 ngx_http_image_length(ngx_http_request_t *r, ngx_buf_t *b) | |
633 { | |
634 r->headers_out.content_length_n = b->last - b->pos; | |
635 | |
636 if (r->headers_out.content_length) { | |
637 r->headers_out.content_length->hash = 0; | |
638 } | |
639 | |
640 r->headers_out.content_length = NULL; | |
641 } | |
642 | |
643 | |
644 static ngx_int_t | |
645 ngx_http_image_size(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
646 { | |
647 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
|
648 size_t len, app; |
2788 | 649 ngx_uint_t width, height; |
650 | |
651 p = ctx->image; | |
652 | |
653 switch (ctx->type) { | |
654 | |
655 case NGX_HTTP_IMAGE_JPEG: | |
656 | |
657 p += 2; | |
658 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
|
659 width = 0; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
660 height = 0; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
661 app = 0; |
2788 | 662 |
663 while (p < last) { | |
664 | |
665 if (p[0] == 0xff && p[1] != 0xff) { | |
666 | |
667 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
3393 | 668 "JPEG: %02xd %02xd", p[0], p[1]); |
2788 | 669 |
670 p++; | |
671 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
672 if ((*p == 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
|
673 || *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
|
674 && (width == 0 || height == 0)) |
2788 | 675 { |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
676 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
|
677 height = p[4] * 256 + p[5]; |
2788 | 678 } |
679 | |
680 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
681 "JPEG: %02xd %02xd", p[1], p[2]); | |
682 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
683 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
|
684 |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
685 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
|
686 /* 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
|
687 app += len; |
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
688 } |
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 p += len; |
2788 | 691 |
692 continue; | |
693 } | |
694 | |
695 p++; | |
696 } | |
697 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
698 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
|
699 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
|
700 } |
2788 | 701 |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
702 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
|
703 /* 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
|
704 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
|
705 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
|
706 "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
|
707 } |
2788 | 708 |
709 break; | |
710 | |
711 case NGX_HTTP_IMAGE_GIF: | |
712 | |
713 if (ctx->length < 10) { | |
714 return NGX_DECLINED; | |
715 } | |
716 | |
717 width = p[7] * 256 + p[6]; | |
718 height = p[9] * 256 + p[8]; | |
719 | |
720 break; | |
721 | |
722 case NGX_HTTP_IMAGE_PNG: | |
723 | |
724 if (ctx->length < 24) { | |
725 return NGX_DECLINED; | |
726 } | |
727 | |
728 width = p[18] * 256 + p[19]; | |
729 height = p[22] * 256 + p[23]; | |
730 | |
731 break; | |
732 | |
733 default: | |
734 | |
735 return NGX_DECLINED; | |
736 } | |
737 | |
738 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
739 "image size: %d x %d", width, height); | |
740 | |
741 ctx->width = width; | |
742 ctx->height = height; | |
743 | |
744 return NGX_OK; | |
745 } | |
746 | |
747 | |
748 static ngx_buf_t * | |
749 ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
750 { | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
751 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
|
752 colors, palette, transparent, sharpen, |
3878 | 753 red, green, blue, t; |
2788 | 754 u_char *out; |
755 ngx_buf_t *b; | |
756 ngx_uint_t resize; | |
757 gdImagePtr src, dst; | |
758 ngx_pool_cleanup_t *cln; | |
759 ngx_http_image_filter_conf_t *conf; | |
760 | |
761 src = ngx_http_image_source(r, ctx); | |
762 | |
763 if (src == NULL) { | |
764 return NULL; | |
765 } | |
766 | |
767 sx = gdImageSX(src); | |
768 sy = gdImageSY(src); | |
769 | |
770 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | |
771 | |
3394
11965c62b92c
force image filter conversion if JPEG application data consume more than 5%
Igor Sysoev <igor@sysoev.ru>
parents:
3393
diff
changeset
|
772 if (!ctx->force |
3878 | 773 && 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
|
774 && (ngx_uint_t) sx <= ctx->max_width |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
775 && (ngx_uint_t) sy <= ctx->max_height) |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
776 { |
2788 | 777 gdImageDestroy(src); |
778 return ngx_http_image_asis(r, ctx); | |
779 } | |
780 | |
781 colors = gdImageColorsTotal(src); | |
3134 | 782 |
783 if (colors && conf->transparency) { | |
784 transparent = gdImageGetTransparent(src); | |
785 | |
786 if (transparent != -1) { | |
787 palette = colors; | |
788 red = gdImageRed(src, transparent); | |
789 green = gdImageGreen(src, transparent); | |
790 blue = gdImageBlue(src, transparent); | |
2788 | 791 |
3134 | 792 goto transparent; |
793 } | |
794 } | |
3117 | 795 |
3134 | 796 palette = 0; |
797 transparent = -1; | |
798 red = 0; | |
799 green = 0; | |
800 blue = 0; | |
801 | |
802 transparent: | |
803 | |
804 gdImageColorTransparent(src, -1); | |
3117 | 805 |
2788 | 806 dx = sx; |
807 dy = sy; | |
808 | |
809 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { | |
810 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
811 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
812 dy = dy * ctx->max_width / dx; |
2788 | 813 dy = dy ? dy : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
814 dx = ctx->max_width; |
2788 | 815 } |
816 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
817 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
818 dx = dx * ctx->max_height / dy; |
2788 | 819 dx = dx ? dx : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
820 dy = ctx->max_height; |
2788 | 821 } |
822 | |
823 resize = 1; | |
824 | |
3878 | 825 } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) { |
826 | |
827 resize = 0; | |
828 | |
2788 | 829 } else { /* NGX_HTTP_IMAGE_CROP */ |
830 | |
831 resize = 0; | |
832 | |
4601
084137d883ec
Image filter: compare aspect ratio more accurately during crop.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4412
diff
changeset
|
833 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
|
834 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
835 dy = dy * ctx->max_width / dx; |
2788 | 836 dy = dy ? dy : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
837 dx = ctx->max_width; |
2788 | 838 resize = 1; |
839 } | |
840 | |
841 } else { | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
842 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
843 dx = dx * ctx->max_height / dy; |
2788 | 844 dx = dx ? dx : 1; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
845 dy = ctx->max_height; |
2788 | 846 resize = 1; |
847 } | |
848 } | |
849 } | |
850 | |
851 if (resize) { | |
3134 | 852 dst = ngx_http_image_new(r, dx, dy, palette); |
2788 | 853 if (dst == NULL) { |
854 gdImageDestroy(src); | |
855 return NULL; | |
856 } | |
857 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
858 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
859 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
860 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
861 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
862 |
2788 | 863 gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); |
864 | |
3134 | 865 if (colors) { |
866 gdImageTrueColorToPalette(dst, 1, 256); | |
867 } | |
868 | |
2788 | 869 gdImageDestroy(src); |
870 | |
871 } else { | |
872 dst = src; | |
873 } | |
874 | |
3878 | 875 if (ctx->angle) { |
876 src = dst; | |
877 | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
878 ax = (dx % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
879 ay = (dy % 2 == 0) ? 1 : 0; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
880 |
3878 | 881 switch (ctx->angle) { |
882 | |
883 case 90: | |
884 case 270: | |
885 dst = ngx_http_image_new(r, dy, dx, palette); | |
886 if (dst == NULL) { | |
887 gdImageDestroy(src); | |
888 return NULL; | |
889 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
890 if (ctx->angle == 90) { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
891 ox = dy / 2 + ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
892 oy = dx / 2 - ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
893 |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
894 } else { |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
895 ox = dy / 2 - ay; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
896 oy = dx / 2 + ax; |
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
897 } |
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 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
|
900 dx + ax, dy + ay, ctx->angle); |
3878 | 901 gdImageDestroy(src); |
3884
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
902 |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
903 t = dx; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
904 dx = dy; |
ea712f4dc030
fix "image_filter rotate 180" and crop case
Igor Sysoev <igor@sysoev.ru>
parents:
3878
diff
changeset
|
905 dy = t; |
3878 | 906 break; |
907 | |
908 case 180: | |
909 dst = ngx_http_image_new(r, dx, dy, palette); | |
910 if (dst == NULL) { | |
911 gdImageDestroy(src); | |
912 return NULL; | |
913 } | |
3910
750fb808aa15
gdImageCopyRotated() may images of even height or width
Igor Sysoev <igor@sysoev.ru>
parents:
3884
diff
changeset
|
914 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
|
915 dx + ax, dy + ay, ctx->angle); |
3878 | 916 gdImageDestroy(src); |
917 break; | |
918 } | |
919 } | |
920 | |
2788 | 921 if (conf->filter == NGX_HTTP_IMAGE_CROP) { |
922 | |
923 src = dst; | |
924 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
925 if ((ngx_uint_t) dx > ctx->max_width) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
926 ox = dx - ctx->max_width; |
2788 | 927 |
928 } else { | |
929 ox = 0; | |
930 } | |
931 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
932 if ((ngx_uint_t) dy > ctx->max_height) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
933 oy = dy - ctx->max_height; |
2788 | 934 |
935 } else { | |
936 oy = 0; | |
937 } | |
938 | |
939 if (ox || oy) { | |
940 | |
941 dst = ngx_http_image_new(r, dx - ox, dy - oy, colors); | |
942 | |
943 if (dst == NULL) { | |
944 gdImageDestroy(src); | |
945 return NULL; | |
946 } | |
947 | |
948 ox /= 2; | |
949 oy /= 2; | |
950 | |
951 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
952 "image crop: %d x %d @ %d x %d", | |
953 dx, dy, ox, oy); | |
954 | |
3133
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
955 if (colors == 0) { |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
956 gdImageSaveAlpha(dst, 1); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
957 gdImageAlphaBlending(dst, 0); |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
958 } |
28a6aa24b453
fix alpha-channel transparency in PNG
Igor Sysoev <igor@sysoev.ru>
parents:
3117
diff
changeset
|
959 |
2788 | 960 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); |
961 | |
3134 | 962 if (colors) { |
963 gdImageTrueColorToPalette(dst, 1, 256); | |
964 } | |
965 | |
2788 | 966 gdImageDestroy(src); |
967 } | |
968 } | |
969 | |
3117 | 970 if (transparent != -1 && colors) { |
971 gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); | |
972 } | |
2788 | 973 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
974 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
|
975 if (sharpen > 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
976 gdImageSharpen(dst, sharpen); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
977 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
978 |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
979 gdImageInterlace(dst, (int) conf->interlace); |
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
980 |
2788 | 981 out = ngx_http_image_out(r, ctx->type, dst, &size); |
982 | |
983 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
984 "image: %d x %d %d", sx, sy, colors); | |
985 | |
986 gdImageDestroy(dst); | |
987 ngx_pfree(r->pool, ctx->image); | |
988 | |
989 if (out == NULL) { | |
990 return NULL; | |
991 } | |
992 | |
993 cln = ngx_pool_cleanup_add(r->pool, 0); | |
994 if (cln == NULL) { | |
995 gdFree(out); | |
996 return NULL; | |
997 } | |
998 | |
999 b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t)); | |
1000 if (b == NULL) { | |
1001 gdFree(out); | |
1002 return NULL; | |
1003 } | |
1004 | |
1005 cln->handler = ngx_http_image_cleanup; | |
1006 cln->data = out; | |
1007 | |
1008 b->pos = out; | |
1009 b->last = out + size; | |
1010 b->memory = 1; | |
1011 b->last_buf = 1; | |
1012 | |
1013 ngx_http_image_length(r, b); | |
1014 | |
1015 return b; | |
1016 } | |
1017 | |
1018 | |
1019 static gdImagePtr | |
1020 ngx_http_image_source(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | |
1021 { | |
1022 char *failed; | |
1023 gdImagePtr img; | |
1024 | |
1025 img = NULL; | |
1026 | |
1027 switch (ctx->type) { | |
1028 | |
1029 case NGX_HTTP_IMAGE_JPEG: | |
1030 img = gdImageCreateFromJpegPtr(ctx->length, ctx->image); | |
1031 failed = "gdImageCreateFromJpegPtr() failed"; | |
1032 break; | |
1033 | |
1034 case NGX_HTTP_IMAGE_GIF: | |
1035 img = gdImageCreateFromGifPtr(ctx->length, ctx->image); | |
1036 failed = "gdImageCreateFromGifPtr() failed"; | |
1037 break; | |
1038 | |
1039 case NGX_HTTP_IMAGE_PNG: | |
1040 img = gdImageCreateFromPngPtr(ctx->length, ctx->image); | |
1041 failed = "gdImageCreateFromPngPtr() failed"; | |
1042 break; | |
1043 | |
1044 default: | |
1045 failed = "unknown image type"; | |
1046 break; | |
1047 } | |
1048 | |
1049 if (img == NULL) { | |
1050 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1051 } | |
1052 | |
1053 return img; | |
1054 } | |
1055 | |
1056 | |
1057 static gdImagePtr | |
1058 ngx_http_image_new(ngx_http_request_t *r, int w, int h, int colors) | |
1059 { | |
1060 gdImagePtr img; | |
1061 | |
1062 if (colors == 0) { | |
1063 img = gdImageCreateTrueColor(w, h); | |
1064 | |
1065 if (img == NULL) { | |
1066 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1067 "gdImageCreateTrueColor() failed"); | |
1068 return NULL; | |
1069 } | |
1070 | |
1071 } else { | |
1072 img = gdImageCreate(w, h); | |
1073 | |
1074 if (img == NULL) { | |
1075 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | |
1076 "gdImageCreate() failed"); | |
1077 return NULL; | |
1078 } | |
1079 } | |
1080 | |
1081 return img; | |
1082 } | |
1083 | |
1084 | |
1085 static u_char * | |
1086 ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, | |
1087 int *size) | |
1088 { | |
2848 | 1089 char *failed; |
1090 u_char *out; | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1091 ngx_int_t jq; |
2848 | 1092 ngx_http_image_filter_conf_t *conf; |
2788 | 1093 |
1094 out = NULL; | |
1095 | |
1096 switch (type) { | |
1097 | |
1098 case NGX_HTTP_IMAGE_JPEG: | |
2848 | 1099 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
|
1100 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1101 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
|
1102 if (jq <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1103 return NULL; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1104 } |
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 out = gdImageJpegPtr(img, size, jq); |
2788 | 1107 failed = "gdImageJpegPtr() failed"; |
1108 break; | |
1109 | |
1110 case NGX_HTTP_IMAGE_GIF: | |
1111 out = gdImageGifPtr(img, size); | |
1112 failed = "gdImageGifPtr() failed"; | |
1113 break; | |
1114 | |
1115 case NGX_HTTP_IMAGE_PNG: | |
1116 out = gdImagePngPtr(img, size); | |
1117 failed = "gdImagePngPtr() failed"; | |
1118 break; | |
1119 | |
1120 default: | |
1121 failed = "unknown image type"; | |
1122 break; | |
1123 } | |
1124 | |
1125 if (out == NULL) { | |
1126 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, failed); | |
1127 } | |
1128 | |
1129 return out; | |
1130 } | |
1131 | |
1132 | |
1133 static void | |
1134 ngx_http_image_cleanup(void *data) | |
1135 { | |
1136 gdFree(data); | |
1137 } | |
1138 | |
1139 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1140 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1141 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
|
1142 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
|
1143 { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1144 ngx_str_t val; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1145 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1146 if (cv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1147 return v; |
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 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1150 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
|
1151 return 0; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1152 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1153 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1154 return ngx_http_image_filter_value(&val); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1155 } |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1156 |
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 static ngx_uint_t |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1159 ngx_http_image_filter_value(ngx_str_t *value) |
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 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1162 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1163 if (value->len == 1 && value->data[0] == '-') { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1164 return (ngx_uint_t) -1; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1165 } |
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 n = ngx_atoi(value->data, value->len); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1168 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1169 if (n > 0) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1170 return (ngx_uint_t) n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1171 } |
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 return 0; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1174 } |
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 |
2788 | 1177 static void * |
1178 ngx_http_image_filter_create_conf(ngx_conf_t *cf) | |
1179 { | |
1180 ngx_http_image_filter_conf_t *conf; | |
1181 | |
1182 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_image_filter_conf_t)); | |
1183 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
|
1184 return NULL; |
2788 | 1185 } |
1186 | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1187 /* |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1188 * set by ngx_pcalloc(): |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1189 * |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1190 * conf->width = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1191 * conf->height = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1192 * conf->angle = 0; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1193 * conf->wcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1194 * conf->hcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1195 * conf->acv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1196 * conf->jqcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1197 * conf->shcv = NULL; |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1198 */ |
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1199 |
2788 | 1200 conf->filter = NGX_CONF_UNSET_UINT; |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1201 conf->jpeg_quality = NGX_CONF_UNSET_UINT; |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1202 conf->sharpen = NGX_CONF_UNSET_UINT; |
3134 | 1203 conf->transparency = NGX_CONF_UNSET; |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
1204 conf->interlace = NGX_CONF_UNSET; |
2788 | 1205 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
1206 | |
1207 return conf; | |
1208 } | |
1209 | |
1210 | |
1211 static char * | |
1212 ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
1213 { | |
1214 ngx_http_image_filter_conf_t *prev = parent; | |
1215 ngx_http_image_filter_conf_t *conf = child; | |
1216 | |
1217 if (conf->filter == NGX_CONF_UNSET_UINT) { | |
1218 | |
1219 if (prev->filter == NGX_CONF_UNSET_UINT) { | |
1220 conf->filter = NGX_HTTP_IMAGE_OFF; | |
1221 | |
1222 } else { | |
1223 conf->filter = prev->filter; | |
1224 conf->width = prev->width; | |
1225 conf->height = prev->height; | |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1226 conf->angle = prev->angle; |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1227 conf->wcv = prev->wcv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1228 conf->hcv = prev->hcv; |
4981
5889bc5f7a65
Image filter: fixed image_filter rotate inheritance.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4978
diff
changeset
|
1229 conf->acv = prev->acv; |
2788 | 1230 } |
1231 } | |
1232 | |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1233 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
|
1234 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1235 /* 75 is libjpeg default quality */ |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1236 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
|
1237 |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1238 if (conf->jqcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1239 conf->jqcv = prev->jqcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1240 } |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1241 } |
2848 | 1242 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1243 if (conf->sharpen == NGX_CONF_UNSET_UINT) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1244 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
|
1245 |
4978
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1246 if (conf->shcv == NULL) { |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1247 conf->shcv = prev->shcv; |
55ccb9f75668
Image filter: configuration inheritance fixes.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4601
diff
changeset
|
1248 } |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1249 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1250 |
3134 | 1251 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); |
1252 | |
5118
af155fc41deb
Image filter: the "image_filter_interlace" directive.
Ruslan Ermilov <ru@nginx.com>
parents:
4981
diff
changeset
|
1253 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
|
1254 |
2788 | 1255 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1256 1 * 1024 * 1024); | |
1257 | |
1258 return NGX_CONF_OK; | |
1259 } | |
1260 | |
1261 | |
1262 static char * | |
1263 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
1264 { | |
1265 ngx_http_image_filter_conf_t *imcf = conf; | |
1266 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1267 ngx_str_t *value; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1268 ngx_int_t n; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1269 ngx_uint_t i; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1270 ngx_http_complex_value_t cv; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1271 ngx_http_compile_complex_value_t ccv; |
2788 | 1272 |
1273 value = cf->args->elts; | |
1274 | |
1275 i = 1; | |
1276 | |
1277 if (cf->args->nelts == 2) { | |
1278 if (ngx_strcmp(value[i].data, "off") == 0) { | |
1279 imcf->filter = NGX_HTTP_IMAGE_OFF; | |
1280 | |
1281 } else if (ngx_strcmp(value[i].data, "test") == 0) { | |
1282 imcf->filter = NGX_HTTP_IMAGE_TEST; | |
1283 | |
1284 } else if (ngx_strcmp(value[i].data, "size") == 0) { | |
1285 imcf->filter = NGX_HTTP_IMAGE_SIZE; | |
1286 | |
1287 } else { | |
1288 goto failed; | |
1289 } | |
1290 | |
1291 return NGX_CONF_OK; | |
3878 | 1292 |
1293 } else if (cf->args->nelts == 3) { | |
1294 | |
1295 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
|
1296 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
|
1297 && 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
|
1298 { |
39982fa69482
Fixed "rotate" to always work when combined with "resize/crop".
Ruslan Ermilov <ru@nginx.com>
parents:
4307
diff
changeset
|
1299 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
|
1300 } |
3878 | 1301 |
1302 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1303 | |
1304 ccv.cf = cf; | |
1305 ccv.value = &value[++i]; | |
1306 ccv.complex_value = &cv; | |
1307 | |
1308 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1309 return NGX_CONF_ERROR; | |
1310 } | |
1311 | |
1312 if (cv.lengths == NULL) { | |
1313 n = ngx_http_image_filter_value(&value[i]); | |
1314 | |
1315 if (n != 90 && n != 180 && n != 270) { | |
1316 goto failed; | |
1317 } | |
1318 | |
1319 imcf->angle = (ngx_uint_t) n; | |
1320 | |
1321 } else { | |
1322 imcf->acv = ngx_palloc(cf->pool, | |
1323 sizeof(ngx_http_complex_value_t)); | |
1324 if (imcf->acv == NULL) { | |
1325 return NGX_CONF_ERROR; | |
1326 } | |
1327 | |
1328 *imcf->acv = cv; | |
1329 } | |
1330 | |
1331 return NGX_CONF_OK; | |
1332 | |
1333 } else { | |
1334 goto failed; | |
1335 } | |
2788 | 1336 } |
1337 | |
1338 if (ngx_strcmp(value[i].data, "resize") == 0) { | |
1339 imcf->filter = NGX_HTTP_IMAGE_RESIZE; | |
1340 | |
1341 } else if (ngx_strcmp(value[i].data, "crop") == 0) { | |
1342 imcf->filter = NGX_HTTP_IMAGE_CROP; | |
1343 | |
1344 } else { | |
1345 goto failed; | |
1346 } | |
1347 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1348 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
|
1349 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1350 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1351 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1352 ccv.complex_value = &cv; |
2788 | 1353 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1354 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1355 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1356 } |
2788 | 1357 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1358 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1359 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1360 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1361 if (n == 0) { |
2788 | 1362 goto failed; |
1363 } | |
1364 | |
1365 imcf->width = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1366 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1367 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1368 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
|
1369 if (imcf->wcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1370 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1371 } |
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 *imcf->wcv = cv; |
2788 | 1374 } |
1375 | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1376 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
|
1377 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1378 ccv.cf = cf; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1379 ccv.value = &value[++i]; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1380 ccv.complex_value = &cv; |
2788 | 1381 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1382 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1383 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1384 } |
2788 | 1385 |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1386 if (cv.lengths == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1387 n = ngx_http_image_filter_value(&value[i]); |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1388 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1389 if (n == 0) { |
2788 | 1390 goto failed; |
1391 } | |
1392 | |
1393 imcf->height = (ngx_uint_t) n; | |
2998
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1394 |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1395 } else { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1396 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
|
1397 if (imcf->hcv == NULL) { |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1398 return NGX_CONF_ERROR; |
fa8503fd3647
variables support in image_filter
Igor Sysoev <igor@sysoev.ru>
parents:
2918
diff
changeset
|
1399 } |
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 *imcf->hcv = cv; |
2788 | 1402 } |
1403 | |
1404 return NGX_CONF_OK; | |
1405 | |
1406 failed: | |
1407 | |
1408 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid parameter \"%V\"", | |
1409 &value[i]); | |
1410 | |
1411 return NGX_CONF_ERROR; | |
1412 } | |
1413 | |
1414 | |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1415 static char * |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1416 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
|
1417 void *conf) |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1418 { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1419 ngx_http_image_filter_conf_t *imcf = conf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1420 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1421 ngx_str_t *value; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1422 ngx_int_t n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1423 ngx_http_complex_value_t cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1424 ngx_http_compile_complex_value_t ccv; |
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 value = cf->args->elts; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1427 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1428 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
|
1429 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1430 ccv.cf = cf; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1431 ccv.value = &value[1]; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1432 ccv.complex_value = &cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1433 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1434 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
|
1435 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1436 } |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1437 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1438 if (cv.lengths == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1439 n = ngx_http_image_filter_value(&value[1]); |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1440 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1441 if (n <= 0) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1442 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1443 "invalid value \"%V\"", &value[1]); |
3745
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1444 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1445 } |
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 imcf->jpeg_quality = (ngx_uint_t) n; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1448 |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1449 } else { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1450 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
|
1451 if (imcf->jqcv == NULL) { |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1452 return NGX_CONF_ERROR; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1453 } |
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 *imcf->jqcv = cv; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1456 } |
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 return NGX_CONF_OK; |
f5fa9d2e09b6
image_filter_jpeg_quality supports variables
Igor Sysoev <igor@sysoev.ru>
parents:
3722
diff
changeset
|
1459 } |
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 |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1462 static char * |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1463 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
|
1464 void *conf) |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1465 { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1466 ngx_http_image_filter_conf_t *imcf = conf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1467 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1468 ngx_str_t *value; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1469 ngx_int_t n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1470 ngx_http_complex_value_t cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1471 ngx_http_compile_complex_value_t ccv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1472 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1473 value = cf->args->elts; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1474 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1475 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
|
1476 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1477 ccv.cf = cf; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1478 ccv.value = &value[1]; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1479 ccv.complex_value = &cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1480 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1481 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1482 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1483 } |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1484 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1485 if (cv.lengths == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1486 n = ngx_http_image_filter_value(&value[1]); |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1487 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1488 if (n < 0) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1489 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, |
4307 | 1490 "invalid value \"%V\"", &value[1]); |
4265
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1491 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1492 } |
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 imcf->sharpen = (ngx_uint_t) n; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1495 |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1496 } else { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1497 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
|
1498 if (imcf->shcv == NULL) { |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1499 return NGX_CONF_ERROR; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1500 } |
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 *imcf->shcv = cv; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1503 } |
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 return NGX_CONF_OK; |
01a7e78ff5a1
The "image_filter_sharpen" directive.
Igor Sysoev <igor@sysoev.ru>
parents:
3910
diff
changeset
|
1506 } |
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 |
2788 | 1509 static ngx_int_t |
1510 ngx_http_image_filter_init(ngx_conf_t *cf) | |
1511 { | |
1512 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
1513 ngx_http_top_header_filter = ngx_http_image_header_filter; | |
1514 | |
1515 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
1516 ngx_http_top_body_filter = ngx_http_image_body_filter; | |
1517 | |
1518 return NGX_OK; | |
1519 } |