Mercurial > hg > nginx-quic
annotate src/http/modules/ngx_http_image_filter_module.c @ 4117:103b0d9afe07
Upstream: content_length_n API change.
We no longer use r->headers_out.content_length_n as a primary source of
backend's response length. Instead we parse response length to
u->headers_in.content_length_n and copy to r->headers_out.content_length_n
when needed.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 15 Sep 2011 18:33:43 +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 } |