Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_image_filter_module.c @ 3244:8b2d478de54b stable-0.7
merge r2999, r3118, r3134, r3135:
various image filter fixes and features:
*) variables support in image_filter
*) fix transparency in GIF
*) fix alpha-channel transparency in PNG
*) image_filter_transparency
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 26 Oct 2009 16:56:49 +0000 |
parents | 2efa8d2fcde1 |
children | d87088142876 |
comparison
equal
deleted
inserted
replaced
3243:08570d26c7c5 | 3244:8b2d478de54b |
---|---|
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_int_t jpeg_quality; |
42 | 42 |
43 ngx_flag_t transparency; | |
44 | |
45 ngx_http_complex_value_t *wcv; | |
46 ngx_http_complex_value_t *hcv; | |
47 | |
43 size_t buffer_size; | 48 size_t buffer_size; |
44 } ngx_http_image_filter_conf_t; | 49 } ngx_http_image_filter_conf_t; |
45 | 50 |
46 | 51 |
47 typedef struct { | 52 typedef struct { |
50 | 55 |
51 size_t length; | 56 size_t length; |
52 | 57 |
53 ngx_uint_t width; | 58 ngx_uint_t width; |
54 ngx_uint_t height; | 59 ngx_uint_t height; |
60 | |
61 ngx_uint_t max_width; | |
62 ngx_uint_t max_height; | |
55 | 63 |
56 ngx_uint_t phase; | 64 ngx_uint_t phase; |
57 ngx_uint_t type; | 65 ngx_uint_t type; |
58 } ngx_http_image_filter_ctx_t; | 66 } ngx_http_image_filter_ctx_t; |
59 | 67 |
78 static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h, | 86 static gdImagePtr ngx_http_image_new(ngx_http_request_t *r, int w, int h, |
79 int colors); | 87 int colors); |
80 static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, | 88 static u_char *ngx_http_image_out(ngx_http_request_t *r, ngx_uint_t type, |
81 gdImagePtr img, int *size); | 89 gdImagePtr img, int *size); |
82 static void ngx_http_image_cleanup(void *data); | 90 static void ngx_http_image_cleanup(void *data); |
91 static ngx_uint_t ngx_http_image_filter_get_value(ngx_http_request_t *r, | |
92 ngx_http_complex_value_t *cv, ngx_uint_t v); | |
93 static ngx_uint_t ngx_http_image_filter_value(ngx_str_t *value); | |
83 | 94 |
84 | 95 |
85 static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); | 96 static void *ngx_http_image_filter_create_conf(ngx_conf_t *cf); |
86 static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, | 97 static char *ngx_http_image_filter_merge_conf(ngx_conf_t *cf, void *parent, |
87 void *child); | 98 void *child); |
102 { ngx_string("image_filter_jpeg_quality"), | 113 { ngx_string("image_filter_jpeg_quality"), |
103 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 114 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
104 ngx_conf_set_num_slot, | 115 ngx_conf_set_num_slot, |
105 NGX_HTTP_LOC_CONF_OFFSET, | 116 NGX_HTTP_LOC_CONF_OFFSET, |
106 offsetof(ngx_http_image_filter_conf_t, jpeg_quality), | 117 offsetof(ngx_http_image_filter_conf_t, jpeg_quality), |
118 NULL }, | |
119 | |
120 { ngx_string("image_filter_transparency"), | |
121 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
122 ngx_conf_set_flag_slot, | |
123 NGX_HTTP_LOC_CONF_OFFSET, | |
124 offsetof(ngx_http_image_filter_conf_t, transparency), | |
107 NULL }, | 125 NULL }, |
108 | 126 |
109 { ngx_string("image_filter_buffer"), | 127 { ngx_string("image_filter_buffer"), |
110 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | 128 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, |
111 ngx_conf_set_size_slot, | 129 ngx_conf_set_size_slot, |
452 | 470 |
453 | 471 |
454 static ngx_buf_t * | 472 static ngx_buf_t * |
455 ngx_http_image_process(ngx_http_request_t *r) | 473 ngx_http_image_process(ngx_http_request_t *r) |
456 { | 474 { |
457 ngx_buf_t *b; | |
458 ngx_int_t rc; | 475 ngx_int_t rc; |
459 ngx_http_image_filter_ctx_t *ctx; | 476 ngx_http_image_filter_ctx_t *ctx; |
460 ngx_http_image_filter_conf_t *conf; | 477 ngx_http_image_filter_conf_t *conf; |
461 | 478 |
462 r->connection->buffered &= ~NGX_HTTP_IMAGE_BUFFERED; | 479 r->connection->buffered &= ~NGX_HTTP_IMAGE_BUFFERED; |
466 rc = ngx_http_image_size(r, ctx); | 483 rc = ngx_http_image_size(r, ctx); |
467 | 484 |
468 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | 485 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
469 | 486 |
470 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { | 487 if (conf->filter == NGX_HTTP_IMAGE_SIZE) { |
471 | 488 return ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL); |
472 b = ngx_http_image_json(r, rc == NGX_OK ? ctx : NULL); | 489 } |
473 | 490 |
474 } else if (rc == NGX_OK | 491 ctx->max_width = ngx_http_image_filter_get_value(r, conf->wcv, conf->width); |
475 && ctx->width <= conf->width | 492 if (ctx->max_width == 0) { |
476 && ctx->height <= conf->height) | 493 return NULL; |
494 } | |
495 | |
496 ctx->max_height = ngx_http_image_filter_get_value(r, conf->hcv, | |
497 conf->height); | |
498 if (ctx->max_height == 0) { | |
499 return NULL; | |
500 } | |
501 | |
502 if (rc == NGX_OK | |
503 && ctx->width <= ctx->max_width | |
504 && ctx->height <= ctx->max_height) | |
477 { | 505 { |
478 b = ngx_http_image_asis(r, ctx); | 506 return ngx_http_image_asis(r, ctx); |
479 | 507 } |
480 } else { | 508 |
481 b = ngx_http_image_resize(r, ctx); | 509 return ngx_http_image_resize(r, ctx); |
482 } | |
483 | |
484 return b; | |
485 } | 510 } |
486 | 511 |
487 | 512 |
488 static ngx_buf_t * | 513 static ngx_buf_t * |
489 ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | 514 ngx_http_image_json(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) |
660 | 685 |
661 | 686 |
662 static ngx_buf_t * | 687 static ngx_buf_t * |
663 ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) | 688 ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx) |
664 { | 689 { |
665 int sx, sy, dx, dy, ox, oy, | 690 int sx, sy, dx, dy, ox, oy, size, |
666 colors, transparent, size; | 691 colors, palette, transparent, |
692 red, green, blue; | |
667 u_char *out; | 693 u_char *out; |
668 ngx_buf_t *b; | 694 ngx_buf_t *b; |
669 ngx_uint_t resize; | 695 ngx_uint_t resize; |
670 gdImagePtr src, dst; | 696 gdImagePtr src, dst; |
671 ngx_pool_cleanup_t *cln; | 697 ngx_pool_cleanup_t *cln; |
680 sx = gdImageSX(src); | 706 sx = gdImageSX(src); |
681 sy = gdImageSY(src); | 707 sy = gdImageSY(src); |
682 | 708 |
683 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); | 709 conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module); |
684 | 710 |
685 if ((ngx_uint_t) sx <= conf->width && (ngx_uint_t) sy <= conf->height) { | 711 if ((ngx_uint_t) sx <= ctx->max_width |
712 && (ngx_uint_t) sy <= ctx->max_height) | |
713 { | |
686 gdImageDestroy(src); | 714 gdImageDestroy(src); |
687 return ngx_http_image_asis(r, ctx); | 715 return ngx_http_image_asis(r, ctx); |
688 } | 716 } |
689 | 717 |
690 colors = gdImageColorsTotal(src); | 718 colors = gdImageColorsTotal(src); |
691 transparent = gdImageGetTransparent(src); | 719 |
720 if (colors && conf->transparency) { | |
721 transparent = gdImageGetTransparent(src); | |
722 | |
723 if (transparent != -1) { | |
724 palette = colors; | |
725 red = gdImageRed(src, transparent); | |
726 green = gdImageGreen(src, transparent); | |
727 blue = gdImageBlue(src, transparent); | |
728 | |
729 goto transparent; | |
730 } | |
731 } | |
732 | |
733 palette = 0; | |
734 transparent = -1; | |
735 red = 0; | |
736 green = 0; | |
737 blue = 0; | |
738 | |
739 transparent: | |
740 | |
741 gdImageColorTransparent(src, -1); | |
692 | 742 |
693 dx = sx; | 743 dx = sx; |
694 dy = sy; | 744 dy = sy; |
695 | 745 |
696 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { | 746 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { |
697 | 747 |
698 if ((ngx_uint_t) dx > conf->width) { | 748 if ((ngx_uint_t) dx > ctx->max_width) { |
699 dy = dy * conf->width / dx; | 749 dy = dy * ctx->max_width / dx; |
700 dy = dy ? dy : 1; | 750 dy = dy ? dy : 1; |
701 dx = conf->width; | 751 dx = ctx->max_width; |
702 } | 752 } |
703 | 753 |
704 if ((ngx_uint_t) dy > conf->height) { | 754 if ((ngx_uint_t) dy > ctx->max_height) { |
705 dx = dx * conf->height / dy; | 755 dx = dx * ctx->max_height / dy; |
706 dx = dx ? dx : 1; | 756 dx = dx ? dx : 1; |
707 dy = conf->height; | 757 dy = ctx->max_height; |
708 } | 758 } |
709 | 759 |
710 resize = 1; | 760 resize = 1; |
711 | 761 |
712 } else { /* NGX_HTTP_IMAGE_CROP */ | 762 } else { /* NGX_HTTP_IMAGE_CROP */ |
713 | 763 |
714 resize = 0; | 764 resize = 0; |
715 | 765 |
716 if ((ngx_uint_t) (dx * 100 / dy) < conf->width * 100 / conf->height) { | 766 if ((ngx_uint_t) (dx * 100 / dy) |
717 | 767 < ctx->max_width * 100 / ctx->max_height) |
718 if ((ngx_uint_t) dx > conf->width) { | 768 { |
719 dy = dy * conf->width / dx; | 769 if ((ngx_uint_t) dx > ctx->max_width) { |
770 dy = dy * ctx->max_width / dx; | |
720 dy = dy ? dy : 1; | 771 dy = dy ? dy : 1; |
721 dx = conf->width; | 772 dx = ctx->max_width; |
722 resize = 1; | 773 resize = 1; |
723 } | 774 } |
724 | 775 |
725 } else { | 776 } else { |
726 if ((ngx_uint_t) dy > conf->height) { | 777 if ((ngx_uint_t) dy > ctx->max_height) { |
727 dx = dx * conf->height / dy; | 778 dx = dx * ctx->max_height / dy; |
728 dx = dx ? dx : 1; | 779 dx = dx ? dx : 1; |
729 dy = conf->height; | 780 dy = ctx->max_height; |
730 resize = 1; | 781 resize = 1; |
731 } | 782 } |
732 } | 783 } |
733 } | 784 } |
734 | 785 |
735 if (resize) { | 786 if (resize) { |
736 dst = ngx_http_image_new(r, dx, dy, colors); | 787 dst = ngx_http_image_new(r, dx, dy, palette); |
737 if (dst == NULL) { | 788 if (dst == NULL) { |
738 gdImageDestroy(src); | 789 gdImageDestroy(src); |
739 return NULL; | 790 return NULL; |
740 } | 791 } |
741 | 792 |
793 if (colors == 0) { | |
794 gdImageSaveAlpha(dst, 1); | |
795 gdImageAlphaBlending(dst, 0); | |
796 } | |
797 | |
742 gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); | 798 gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy); |
799 | |
800 if (colors) { | |
801 gdImageTrueColorToPalette(dst, 1, 256); | |
802 } | |
743 | 803 |
744 gdImageDestroy(src); | 804 gdImageDestroy(src); |
745 | 805 |
746 } else { | 806 } else { |
747 dst = src; | 807 dst = src; |
749 | 809 |
750 if (conf->filter == NGX_HTTP_IMAGE_CROP) { | 810 if (conf->filter == NGX_HTTP_IMAGE_CROP) { |
751 | 811 |
752 src = dst; | 812 src = dst; |
753 | 813 |
754 if ((ngx_uint_t) dx > conf->width) { | 814 if ((ngx_uint_t) dx > ctx->max_width) { |
755 ox = dx - conf->width; | 815 ox = dx - ctx->max_width; |
756 | 816 |
757 } else { | 817 } else { |
758 ox = 0; | 818 ox = 0; |
759 } | 819 } |
760 | 820 |
761 if ((ngx_uint_t) dy > conf->height) { | 821 if ((ngx_uint_t) dy > ctx->max_height) { |
762 oy = dy - conf->height; | 822 oy = dy - ctx->max_height; |
763 | 823 |
764 } else { | 824 } else { |
765 oy = 0; | 825 oy = 0; |
766 } | 826 } |
767 | 827 |
779 | 839 |
780 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 840 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
781 "image crop: %d x %d @ %d x %d", | 841 "image crop: %d x %d @ %d x %d", |
782 dx, dy, ox, oy); | 842 dx, dy, ox, oy); |
783 | 843 |
844 if (colors == 0) { | |
845 gdImageSaveAlpha(dst, 1); | |
846 gdImageAlphaBlending(dst, 0); | |
847 } | |
848 | |
784 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); | 849 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); |
785 | 850 |
851 if (colors) { | |
852 gdImageTrueColorToPalette(dst, 1, 256); | |
853 } | |
854 | |
786 gdImageDestroy(src); | 855 gdImageDestroy(src); |
787 } | 856 } |
788 } | 857 } |
789 | 858 |
790 gdImageColorTransparent(dst, transparent); | 859 if (transparent != -1 && colors) { |
860 gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue)); | |
861 } | |
791 | 862 |
792 out = ngx_http_image_out(r, ctx->type, dst, &size); | 863 out = ngx_http_image_out(r, ctx->type, dst, &size); |
793 | 864 |
794 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 865 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
795 "image: %d x %d %d", sx, sy, colors); | 866 "image: %d x %d %d", sx, sy, colors); |
939 { | 1010 { |
940 gdFree(data); | 1011 gdFree(data); |
941 } | 1012 } |
942 | 1013 |
943 | 1014 |
1015 static ngx_uint_t | |
1016 ngx_http_image_filter_get_value(ngx_http_request_t *r, | |
1017 ngx_http_complex_value_t *cv, ngx_uint_t v) | |
1018 { | |
1019 ngx_str_t val; | |
1020 | |
1021 if (cv == NULL) { | |
1022 return v; | |
1023 } | |
1024 | |
1025 if (ngx_http_complex_value(r, cv, &val) != NGX_OK) { | |
1026 return 0; | |
1027 } | |
1028 | |
1029 return ngx_http_image_filter_value(&val); | |
1030 } | |
1031 | |
1032 | |
1033 static ngx_uint_t | |
1034 ngx_http_image_filter_value(ngx_str_t *value) | |
1035 { | |
1036 ngx_int_t n; | |
1037 | |
1038 if (value->len == 1 && value->data[0] == '-') { | |
1039 return (ngx_uint_t) -1; | |
1040 } | |
1041 | |
1042 n = ngx_atoi(value->data, value->len); | |
1043 | |
1044 if (n > 0) { | |
1045 return (ngx_uint_t) n; | |
1046 } | |
1047 | |
1048 return 0; | |
1049 } | |
1050 | |
1051 | |
944 static void * | 1052 static void * |
945 ngx_http_image_filter_create_conf(ngx_conf_t *cf) | 1053 ngx_http_image_filter_create_conf(ngx_conf_t *cf) |
946 { | 1054 { |
947 ngx_http_image_filter_conf_t *conf; | 1055 ngx_http_image_filter_conf_t *conf; |
948 | 1056 |
951 return NULL; | 1059 return NULL; |
952 } | 1060 } |
953 | 1061 |
954 conf->filter = NGX_CONF_UNSET_UINT; | 1062 conf->filter = NGX_CONF_UNSET_UINT; |
955 conf->jpeg_quality = NGX_CONF_UNSET; | 1063 conf->jpeg_quality = NGX_CONF_UNSET; |
1064 conf->transparency = NGX_CONF_UNSET; | |
956 conf->buffer_size = NGX_CONF_UNSET_SIZE; | 1065 conf->buffer_size = NGX_CONF_UNSET_SIZE; |
957 | 1066 |
958 return conf; | 1067 return conf; |
959 } | 1068 } |
960 | 1069 |
972 | 1081 |
973 } else { | 1082 } else { |
974 conf->filter = prev->filter; | 1083 conf->filter = prev->filter; |
975 conf->width = prev->width; | 1084 conf->width = prev->width; |
976 conf->height = prev->height; | 1085 conf->height = prev->height; |
1086 conf->wcv = prev->wcv; | |
1087 conf->hcv = prev->hcv; | |
977 } | 1088 } |
978 } | 1089 } |
979 | 1090 |
980 /* 75 is libjpeg default quality */ | 1091 /* 75 is libjpeg default quality */ |
981 ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75); | 1092 ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75); |
982 | 1093 |
1094 ngx_conf_merge_value(conf->transparency, prev->transparency, 1); | |
1095 | |
983 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, | 1096 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, |
984 1 * 1024 * 1024); | 1097 1 * 1024 * 1024); |
985 | 1098 |
986 return NGX_CONF_OK; | 1099 return NGX_CONF_OK; |
987 } | 1100 } |
990 static char * | 1103 static char * |
991 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 1104 ngx_http_image_filter(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
992 { | 1105 { |
993 ngx_http_image_filter_conf_t *imcf = conf; | 1106 ngx_http_image_filter_conf_t *imcf = conf; |
994 | 1107 |
995 ngx_str_t *value; | 1108 ngx_str_t *value; |
996 ngx_int_t n; | 1109 ngx_int_t n; |
997 ngx_uint_t i; | 1110 ngx_uint_t i; |
1111 ngx_http_complex_value_t cv; | |
1112 ngx_http_compile_complex_value_t ccv; | |
998 | 1113 |
999 value = cf->args->elts; | 1114 value = cf->args->elts; |
1000 | 1115 |
1001 i = 1; | 1116 i = 1; |
1002 | 1117 |
1025 | 1140 |
1026 } else { | 1141 } else { |
1027 goto failed; | 1142 goto failed; |
1028 } | 1143 } |
1029 | 1144 |
1030 i++; | 1145 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); |
1031 | 1146 |
1032 if (value[i].len == 1 && value[i].data[0] == '-') { | 1147 ccv.cf = cf; |
1033 imcf->width = (ngx_uint_t) -1; | 1148 ccv.value = &value[++i]; |
1149 ccv.complex_value = &cv; | |
1150 | |
1151 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1152 return NGX_CONF_ERROR; | |
1153 } | |
1154 | |
1155 if (cv.lengths == NULL) { | |
1156 n = ngx_http_image_filter_value(&value[i]); | |
1157 | |
1158 if (n == 0) { | |
1159 goto failed; | |
1160 } | |
1161 | |
1162 imcf->width = (ngx_uint_t) n; | |
1034 | 1163 |
1035 } else { | 1164 } else { |
1036 n = ngx_atoi(value[i].data, value[i].len); | 1165 imcf->wcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
1037 if (n == NGX_ERROR) { | 1166 if (imcf->wcv == NULL) { |
1167 return NGX_CONF_ERROR; | |
1168 } | |
1169 | |
1170 *imcf->wcv = cv; | |
1171 } | |
1172 | |
1173 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t)); | |
1174 | |
1175 ccv.cf = cf; | |
1176 ccv.value = &value[++i]; | |
1177 ccv.complex_value = &cv; | |
1178 | |
1179 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) { | |
1180 return NGX_CONF_ERROR; | |
1181 } | |
1182 | |
1183 if (cv.lengths == NULL) { | |
1184 n = ngx_http_image_filter_value(&value[i]); | |
1185 | |
1186 if (n == 0) { | |
1038 goto failed; | 1187 goto failed; |
1039 } | 1188 } |
1040 | 1189 |
1041 imcf->width = (ngx_uint_t) n; | 1190 imcf->height = (ngx_uint_t) n; |
1042 } | |
1043 | |
1044 i++; | |
1045 | |
1046 if (value[i].len == 1 && value[i].data[0] == '-') { | |
1047 imcf->height = (ngx_uint_t) -1; | |
1048 | 1191 |
1049 } else { | 1192 } else { |
1050 n = ngx_atoi(value[i].data, value[i].len); | 1193 imcf->hcv = ngx_palloc(cf->pool, sizeof(ngx_http_complex_value_t)); |
1051 if (n == NGX_ERROR) { | 1194 if (imcf->hcv == NULL) { |
1052 goto failed; | 1195 return NGX_CONF_ERROR; |
1053 } | 1196 } |
1054 | 1197 |
1055 imcf->height = (ngx_uint_t) n; | 1198 *imcf->hcv = cv; |
1056 } | 1199 } |
1057 | 1200 |
1058 return NGX_CONF_OK; | 1201 return NGX_CONF_OK; |
1059 | 1202 |
1060 failed: | 1203 failed: |