@@ -929,27 +929,45 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
929929 return res ;
930930}
931931
932+ static inline unsigned char
933+ uchar_clamp (double clr ) {
934+ unsigned short result ;
935+ assert (fabs (clr ) <= SHRT_MAX );
936+ /* Casting a negative float to an unsigned short is undefined.
937+ * However, casting a float to a signed truncates toward zero and
938+ * casting a negative signed value to an unsigned of the same size
939+ * results in a bit-identical value (assuming twos-complement
940+ * arithmetic). This is what we want: all legal negative values
941+ * for clr will be greater than 255. */
942+ /* Convert and clamp. */
943+ result = (unsigned short )(short )(clr + 0.5 );
944+ if (result > 255 ) {
945+ result = (clr < 0 ) ? 0 : 255 ;
946+ }/* if */
947+ return result ;
948+ }/* uchar_clamp*/
949+
932950static inline void _gdScaleRow (gdImagePtr pSrc , unsigned int src_width , gdImagePtr dst , unsigned int dst_width , unsigned int row , LineContribType * contrib )
933951{
934952 int * p_src_row = pSrc -> tpixels [row ];
935953 int * p_dst_row = dst -> tpixels [row ];
936954 unsigned int x ;
937955
938956 for (x = 0 ; x < dst_width ; x ++ ) {
939- register unsigned char r = 0 , g = 0 , b = 0 , a = 0 ;
957+ double r = 0 , g = 0 , b = 0 , a = 0 ;
940958 const int left = contrib -> ContribRow [x ].Left ;
941959 const int right = contrib -> ContribRow [x ].Right ;
942- int i ;
960+ int i ;
943961
944- /* Accumulate each channel */
945- for (i = left ; i <= right ; i ++ ) {
946- const int left_channel = i - left ;
947- r += ( unsigned char )( contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetRed (p_src_row [i ]) ));
948- g += ( unsigned char )( contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetGreen (p_src_row [i ]) ));
949- b += ( unsigned char )( contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetBlue (p_src_row [i ]) ));
950- a += ( unsigned char )( contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetAlpha (p_src_row [i ]) ));
951- }
952- p_dst_row [x ] = gdTrueColorAlpha (r , g , b , a );
962+ /* Accumulate each channel */
963+ for (i = left ; i <= right ; i ++ ) {
964+ const int left_channel = i - left ;
965+ r += contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetRed (p_src_row [i ]));
966+ g += contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetGreen (p_src_row [i ]));
967+ b += contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetBlue (p_src_row [i ]));
968+ a += contrib -> ContribRow [x ].Weights [left_channel ] * (double )(gdTrueColorGetAlpha (p_src_row [i ]));
969+ }
970+ p_dst_row [x ] = gdTrueColorAlpha (uchar_clamp ( r ), uchar_clamp ( g ), uchar_clamp ( b ), uchar_clamp ( a ) );
953971 }
954972}
955973
@@ -982,7 +1000,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
9821000{
9831001 unsigned int y ;
9841002 for (y = 0 ; y < dst_height ; y ++ ) {
985- register unsigned char r = 0 , g = 0 , b = 0 , a = 0 ;
1003+ double r = 0 , g = 0 , b = 0 , a = 0 ;
9861004 const int iLeft = contrib -> ContribRow [y ].Left ;
9871005 const int iRight = contrib -> ContribRow [y ].Right ;
9881006 int i ;
@@ -991,12 +1009,12 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
9911009 for (i = iLeft ; i <= iRight ; i ++ ) {
9921010 const int pCurSrc = pSrc -> tpixels [i ][uCol ];
9931011 const int i_iLeft = i - iLeft ;
994- r += ( unsigned char )( contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetRed (pCurSrc ) ));
995- g += ( unsigned char )( contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetGreen (pCurSrc ) ));
996- b += ( unsigned char )( contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetBlue (pCurSrc ) ));
997- a += ( unsigned char )( contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetAlpha (pCurSrc ) ));
1012+ r += contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetRed (pCurSrc ));
1013+ g += contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetGreen (pCurSrc ));
1014+ b += contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetBlue (pCurSrc ));
1015+ a += contrib -> ContribRow [y ].Weights [i_iLeft ] * (double )(gdTrueColorGetAlpha (pCurSrc ));
9981016 }
999- pRes -> tpixels [y ][uCol ] = gdTrueColorAlpha (r , g , b , a );
1017+ pRes -> tpixels [y ][uCol ] = gdTrueColorAlpha (uchar_clamp ( r ), uchar_clamp ( g ), uchar_clamp ( b ), uchar_clamp ( a ) );
10001018 }
10011019}
10021020
0 commit comments