Mercurial > hg > nginx
comparison src/http/modules/ngx_http_image_filter_module.c @ 3745:f5fa9d2e09b6
image_filter_jpeg_quality supports variables
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Fri, 06 Aug 2010 15:55:05 +0000 |
parents | 1a728cc43bb1 |
children | 7562ee4feb74 |
comparison
equal
deleted
inserted
replaced
3744:77b18d36d123 | 3745:f5fa9d2e09b6 |
---|---|
36 | 36 |
37 typedef struct { | 37 typedef struct { |
38 ngx_uint_t filter; | 38 ngx_uint_t filter; |
39 ngx_uint_t width; | 39 ngx_uint_t width; |
40 ngx_uint_t height; | 40 ngx_uint_t height; |
41 ngx_int_t jpeg_quality; | 41 ngx_uint_t jpeg_quality; |
42 | 42 |
43 ngx_flag_t transparency; | 43 ngx_flag_t transparency; |
44 | 44 |
45 ngx_http_complex_value_t *wcv; | 45 ngx_http_complex_value_t *wcv; |
46 ngx_http_complex_value_t *hcv; | 46 ngx_http_complex_value_t *hcv; |
47 ngx_http_complex_value_t *jqcv; | |
47 | 48 |
48 size_t buffer_size; | 49 size_t buffer_size; |
49 } ngx_http_image_filter_conf_t; | 50 } ngx_http_image_filter_conf_t; |
50 | 51 |
51 | 52 |
97 static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); | 98 static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); |
98 static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, | 99 static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, |
99 void *child); | 100 void *child); |
100 static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, | 101 static char *ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, |
101 void *conf); | 102 void *conf); |
103 static char *ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, | |
104 ngx_command_t *cmd, void *conf); | |
102 static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf); | 105 static ngx_int_t ngx_http_image_filter_init(ngx_conf_t *cf); |
103 | 106 |
104 | 107 |
105 static ngx_command_t ngx_http_image_filter_commands[] = { | 108 static ngx_command_t ngx_http_image_filter_commands[] = { |
106 | 109 |
111 0, | 114 0, |
112 NULL }, | 115 NULL }, |
113 | 116 |
114 { ngx_string("image_filter_jpeg_quality"), | 117 { ngx_string("image_filter_jpeg_quality"), |
115 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 118 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
116 ngx_conf_set_num_slot, | 119 ngx_http_image_filter_jpeg_quality, |
117 NGX_HTTP_LOC_CONF_OFFSET, | 120 NGX_HTTP_LOC_CONF_OFFSET, |
118 offsetof(ngx_http_image_filter_conf_t, jpeg_quality), | 121 0, |
119 NULL }, | 122 NULL }, |
120 | 123 |
121 { ngx_string("image_filter_transparency"), | 124 { ngx_string("image_filter_transparency"), |
122 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | 125 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, |
123 ngx_conf_set_flag_slot, | 126 ngx_conf_set_flag_slot, |
987 ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, | 990 ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, gdImagePtr img, |
988 int *size) | 991 int *size) |
989 { | 992 { |
990 char *failed; | 993 char *failed; |
991 u_char *out; | 994 u_char *out; |
995 ngx_int_t jq; | |
992 ngx_http_image_filter_conf_t *conf; | 996 ngx_http_image_filter_conf_t *conf; |
993 | 997 |
994 out = NULL; | 998 out = NULL; |
995 | 999 |
996 switch (type) { | 1000 switch (type) { |
997 | 1001 |
998 case NGX_HTTP_IMAGE_JPEG: | 1002 case NGX_HTTP_IMAGE_JPEG: |
999 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | 1003 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
1000 out = gdImageJpegPtr(img, size, conf->jpeg_quality); | 1004 |
1005 jq = ngx_http_image_filter_get_value(r, conf->jqcv, conf->jpeg_quality); | |
1006 if (jq <= 0) { | |
1007 return NULL; | |
1008 } | |
1009 | |
1010 out = gdImageJpegPtr(img, size, jq); | |
1001 failed = "gdImageJpegPtr() failed"; | 1011 failed = "gdImageJpegPtr() failed"; |
1002 break; | 1012 break; |
1003 | 1013 |
1004 case NGX_HTTP_IMAGE_GIF: | 1014 case NGX_HTTP_IMAGE_GIF: |
1005 out = gdImageGifPtr(img, size); | 1015 out = gdImageGifPtr(img, size); |
1077 if (conf == NULL) { | 1087 if (conf == NULL) { |
1078 return NULL; | 1088 return NULL; |
1079 } | 1089 } |
1080 | 1090 |
1081 conf->filter = NGX_CONF_UNSET_UINT; | 1091 conf->filter = NGX_CONF_UNSET_UINT; |
1082 conf->jpeg_quality = NGX_CONF_UNSET; | 1092 conf->jpeg_quality = NGX_CONF_UNSET_UINT; |
1083 conf->transparency = NGX_CONF_UNSET; | 1093 conf->transparency = NGX_CONF_UNSET; |
1084 conf->buffer_size = NGX_CONF_UNSET_SIZE; | 1094 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
1085 | 1095 |
1086 return conf; | 1096 return conf; |
1087 } | 1097 } |
1106 conf->hcv = prev->hcv; | 1116 conf->hcv = prev->hcv; |
1107 } | 1117 } |
1108 } | 1118 } |
1109 | 1119 |
1110 /* 75 is libjpeg default quality */ | 1120 /* 75 is libjpeg default quality */ |
1111 ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75); | 1121 ngx_conf_merge_uint_value(conf->jpeg_quality, prev->jpeg_quality, 75); |
1122 | |
1123 if (conf->jqcv == NULL) { | |
1124 conf->jqcv = prev->jqcv; | |
1125 } | |
1112 | 1126 |
1113 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); | 1127 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); |
1114 | 1128 |
1115 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, | 1129 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
1116 1 * 1024 * 1024); | 1130 1 * 1024 * 1024); |
1226 | 1240 |
1227 return NGX_CONF_ERROR; | 1241 return NGX_CONF_ERROR; |
1228 } | 1242 } |
1229 | 1243 |
1230 | 1244 |
1245 static char * | |
1246 ngx_http_image_filter_jpeg_quality(ngx_conf_t *cf, ngx_command_t *cmd, | |
1247 void *conf) | |
1248 { | |
1249 ngx_http_image_filter_conf_t *imcf = conf; | |
1250 | |
1251 ngx_str_t *value; | |
1252 ngx_int_t n; | |
1253 ngx_http_complex_value_t cv; | |
1254 ngx_http_compile_complex_value_t ccv; | |
1255 | |
1256 value = cf->args->elts; | |
1257 | |
1258 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1259 | |
1260 ccv.cf = cf; | |
1261 ccv.value = &value[1]; | |
1262 ccv.complex_value = &cv; | |
1263 | |
1264 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1265 return NGX_CONF_ERROR; | |
1266 } | |
1267 | |
1268 if (cv.lengths == NULL) { | |
1269 n = ngx_http_image_filter_value(&value[1]); | |
1270 | |
1271 if (n <= 0) { | |
1272 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, | |
1273 "invalid parameter \"%V\"", &value[1]); | |
1274 return NGX_CONF_ERROR; | |
1275 } | |
1276 | |
1277 imcf->jpeg_quality = (ngx_uint_t) n; | |
1278 | |
1279 } else { | |
1280 imcf->jqcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); | |
1281 if (imcf->jqcv == NULL) { | |
1282 return NGX_CONF_ERROR; | |
1283 } | |
1284 | |
1285 *imcf->jqcv = cv; | |
1286 } | |
1287 | |
1288 return NGX_CONF_OK; | |
1289 } | |
1290 | |
1291 | |
1231 static ngx_int_t | 1292 static ngx_int_t |
1232 ngx_http_image_filter_init(ngx_conf_t *cf) | 1293 ngx_http_image_filter_init(ngx_conf_t *cf) |
1233 { | 1294 { |
1234 ngx_http_next_header_filter = ngx_http_top_header_filter; | 1295 ngx_http_next_header_filter = ngx_http_top_header_filter; |
1235 ngx_http_top_header_filter = ngx_http_image_header_filter; | 1296 ngx_http_top_header_filter = ngx_http_image_header_filter; |