comparison src/http/modules/ngx_http_image_filter_module.c @ 540:005a70f9573b NGINX_0_8_16

nginx 0.8.16 *) Feature: the "image_filter_transparency" directive. *) Bugfix: "addition_types" directive was incorrectly named "addtion_types". *) Bugfix: resolver cache poisoning. Thanks to Matthew Dempsky. *) Bugfix: memory leak in resolver. Thanks to Matthew Dempsky. *) Bugfix: invalid request line in $request variable was written in access_log only if error_log was set to "info" or "debug" level. *) Bugfix: in PNG alpha-channel support in the ngx_http_image_filter_module. *) Bugfix: nginx always added "Vary: Accept-Encoding" response header line, if both "gzip_static" and "gzip_vary" were on. *) Bugfix: in UTF-8 encoding support by "try_files" directive in nginx/Windows. *) Bugfix: in "post_action" directive usage; the bug had appeared in 0.8.11. Thanks to Igor Artemiev.
author Igor Sysoev <http://sysoev.ru>
date Tue, 22 Sep 2009 00:00:00 +0400
parents 0161f3197817
children 2da4537168f8
comparison
equal deleted inserted replaced
538:a607f3a5aefe 540:005a70f9573b
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_int_t jpeg_quality;
42
43 ngx_flag_t transparency;
42 44
43 ngx_http_complex_value_t *wcv; 45 ngx_http_complex_value_t *wcv;
44 ngx_http_complex_value_t *hcv; 46 ngx_http_complex_value_t *hcv;
45 47
46 size_t buffer_size; 48 size_t buffer_size;
111 { ngx_string("image_filter_jpeg_quality"), 113 { ngx_string("image_filter_jpeg_quality"),
112 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,
113 ngx_conf_set_num_slot, 115 ngx_conf_set_num_slot,
114 NGX_HTTP_LOC_CONF_OFFSET, 116 NGX_HTTP_LOC_CONF_OFFSET,
115 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),
116 NULL }, 125 NULL },
117 126
118 { ngx_string("image_filter_buffer"), 127 { ngx_string("image_filter_buffer"),
119 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,
120 ngx_conf_set_size_slot, 129 ngx_conf_set_size_slot,
676 685
677 686
678 static ngx_buf_t * 687 static ngx_buf_t *
679 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)
680 { 689 {
681 int sx, sy, dx, dy, ox, oy, 690 int sx, sy, dx, dy, ox, oy, size,
682 colors, transparent, red, green, blue, size; 691 colors, palette, transparent,
692 red, green, blue;
683 u_char *out; 693 u_char *out;
684 ngx_buf_t *b; 694 ngx_buf_t *b;
685 ngx_uint_t resize; 695 ngx_uint_t resize;
686 gdImagePtr src, dst; 696 gdImagePtr src, dst;
687 ngx_pool_cleanup_t *cln; 697 ngx_pool_cleanup_t *cln;
704 gdImageDestroy(src); 714 gdImageDestroy(src);
705 return ngx_http_image_asis(r, ctx); 715 return ngx_http_image_asis(r, ctx);
706 } 716 }
707 717
708 colors = gdImageColorsTotal(src); 718 colors = gdImageColorsTotal(src);
709 transparent = gdImageGetTransparent(src); 719
710 720 if (colors && conf->transparency) {
711 if (transparent != -1 && colors) { 721 transparent = gdImageGetTransparent(src);
712 red = gdImageRed(src, transparent); 722
713 green = gdImageGreen(src, transparent); 723 if (transparent != -1) {
714 blue = gdImageBlue(src, transparent); 724 palette = colors;
715 gdImageColorTransparent(src, -1); 725 red = gdImageRed(src, transparent);
716 726 green = gdImageGreen(src, transparent);
717 } else { 727 blue = gdImageBlue(src, transparent);
718 red = 0; green = 0; blue = 0; 728
719 } 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);
720 742
721 dx = sx; 743 dx = sx;
722 dy = sy; 744 dy = sy;
723 745
724 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) { 746 if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {
760 } 782 }
761 } 783 }
762 } 784 }
763 785
764 if (resize) { 786 if (resize) {
765 dst = ngx_http_image_new(r, dx, dy, colors); 787 dst = ngx_http_image_new(r, dx, dy, palette);
766 if (dst == NULL) { 788 if (dst == NULL) {
767 gdImageDestroy(src); 789 gdImageDestroy(src);
768 return NULL; 790 return NULL;
769 } 791 }
770 792
793 if (colors == 0) {
794 gdImageSaveAlpha(dst, 1);
795 gdImageAlphaBlending(dst, 0);
796 }
797
771 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 }
772 803
773 gdImageDestroy(src); 804 gdImageDestroy(src);
774 805
775 } else { 806 } else {
776 dst = src; 807 dst = src;
808 839
809 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 840 ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
810 "image crop: %d x %d @ %d x %d", 841 "image crop: %d x %d @ %d x %d",
811 dx, dy, ox, oy); 842 dx, dy, ox, oy);
812 843
844 if (colors == 0) {
845 gdImageSaveAlpha(dst, 1);
846 gdImageAlphaBlending(dst, 0);
847 }
848
813 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy); 849 gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);
850
851 if (colors) {
852 gdImageTrueColorToPalette(dst, 1, 256);
853 }
814 854
815 gdImageDestroy(src); 855 gdImageDestroy(src);
816 } 856 }
817 } 857 }
818 858
1019 return NULL; 1059 return NULL;
1020 } 1060 }
1021 1061
1022 conf->filter = NGX_CONF_UNSET_UINT; 1062 conf->filter = NGX_CONF_UNSET_UINT;
1023 conf->jpeg_quality = NGX_CONF_UNSET; 1063 conf->jpeg_quality = NGX_CONF_UNSET;
1064 conf->transparency = NGX_CONF_UNSET;
1024 conf->buffer_size = NGX_CONF_UNSET_SIZE; 1065 conf->buffer_size = NGX_CONF_UNSET_SIZE;
1025 1066
1026 return conf; 1067 return conf;
1027 } 1068 }
1028 1069
1048 } 1089 }
1049 1090
1050 /* 75 is libjpeg default quality */ 1091 /* 75 is libjpeg default quality */
1051 ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75); 1092 ngx_conf_merge_value(conf->jpeg_quality, prev->jpeg_quality, 75);
1052 1093
1094 ngx_conf_merge_value(conf->transparency, prev->transparency, 1);
1095
1053 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 1096 ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size,
1054 1 * 1024 * 1024); 1097 1 * 1024 * 1024);
1055 1098
1056 return NGX_CONF_OK; 1099 return NGX_CONF_OK;
1057 } 1100 }