comparison src/http/modules/ngx_http_image_filter_module.c @ 594:3436cf38d59e NGINX_0_8_49

nginx 0.8.49 *) Feature: the "image_filter_jpeg_quality" directive supports variables. *) Bugfix: a segmentation fault might occur in a worker process, if the $geoip_region_name variables was used; the bug had appeared in 0.8.48. *) Bugfix: errors intercepted by error_page were cached only for next request; the bug had appeared in 0.8.48.
author Igor Sysoev <http://sysoev.ru>
date Mon, 09 Aug 2010 00:00:00 +0400
parents 09d5f308901f
children b9763778e212
comparison
equal deleted inserted replaced
593:ad310549c5d4 594:3436cf38d59e
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;