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