@@ -919,27 +919,45 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
919919	return  res ;
920920}
921921
922+ static  inline  unsigned char  
923+ uchar_clamp (double  clr ) {
924+ 	unsigned short  result ;
925+ 	assert (fabs (clr ) <= SHRT_MAX );
926+ 	/* Casting a negative float to an unsigned short is undefined. 
927+ 	 * However, casting a float to a signed truncates toward zero and 
928+ 	 * casting a negative signed value to an unsigned of the same size 
929+ 	 * results in a bit-identical value (assuming twos-complement 
930+ 	 * arithmetic).	 This is what we want: all legal negative values 
931+ 	 * for clr will be greater than 255. */ 
932+ 	/* Convert and clamp. */ 
933+ 	result  =  (unsigned short )(short )(clr  +  0.5 );
934+ 	if  (result  >  255 ) {
935+ 		result  =  (clr  <  0 ) ? 0  : 255 ;
936+ 	}/* if */ 
937+ 	return  result ;
938+ }/* uchar_clamp*/ 
939+ 
922940static  inline  void  _gdScaleRow (gdImagePtr  pSrc ,  unsigned int   src_width , gdImagePtr  dst , unsigned int   dst_width , unsigned int   row , LineContribType  * contrib )
923941{
924942    int  * p_src_row  =  pSrc -> tpixels [row ];
925943    int  * p_dst_row  =  dst -> tpixels [row ];
926944	unsigned int   x ;
927945
928946    for  (x  =  0 ; x  <  dst_width ; x ++ ) {
929- 		register  unsigned  char   r  =  0 , g  =  0 , b  =  0 , a  =  0 ;
947+ 	     double  r  =  0 , g  =  0 , b  =  0 , a  =  0 ;
930948        const  int  left  =  contrib -> ContribRow [x ].Left ;
931949        const  int  right  =  contrib -> ContribRow [x ].Right ;
932- 		 int  i ;
950+ 	int  i ;
933951
934- 		 /* Accumulate each channel */ 
935-          for  (i  =  left ; i  <= right ; i ++ ) {
936- 			 const  int  left_channel  =  i  -  left ;
937-              r  +=  ( unsigned  char )( contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetRed (p_src_row [i ]) ));
938-              g  +=  ( unsigned  char )( contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetGreen (p_src_row [i ]) ));
939-              b  +=  ( unsigned  char )( contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetBlue (p_src_row [i ]) ));
940- 			 a  +=  ( unsigned  char )( contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetAlpha (p_src_row [i ]) ));
941-          }
942-          p_dst_row [x ] =  gdTrueColorAlpha (r ,  g ,  b ,  a );
952+ 	/* Accumulate each channel */ 
953+ 	 for  (i  =  left ; i  <= right ; i ++ ) {
954+ 		const  int  left_channel  =  i  -  left ;
955+ 		 r  +=  contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetRed (p_src_row [i ]));
956+ 		 g  +=  contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetGreen (p_src_row [i ]));
957+ 		 b  +=  contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetBlue (p_src_row [i ]));
958+ 		a  +=  contrib -> ContribRow [x ].Weights [left_channel ] *  (double )(gdTrueColorGetAlpha (p_src_row [i ]));
959+ 	 }
960+ 	 p_dst_row [x ] =  gdTrueColorAlpha (uchar_clamp ( r ),  uchar_clamp ( g ),  uchar_clamp ( b ),  uchar_clamp ( a ) );
943961    }
944962}
945963
@@ -972,7 +990,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc,  unsigned int src_width, gdImag
972990{
973991	unsigned int   y ;
974992	for  (y  =  0 ; y  <  dst_height ; y ++ ) {
975- 		register  unsigned  char   r  =  0 , g  =  0 , b  =  0 , a  =  0 ;
993+ 		double  r  =  0 , g  =  0 , b  =  0 , a  =  0 ;
976994		const  int  iLeft  =  contrib -> ContribRow [y ].Left ;
977995		const  int  iRight  =  contrib -> ContribRow [y ].Right ;
978996		int  i ;
@@ -981,12 +999,12 @@ static inline void _gdScaleCol (gdImagePtr pSrc,  unsigned int src_width, gdImag
981999		for  (i  =  iLeft ; i  <= iRight ; i ++ ) {
9821000			const  int  pCurSrc  =  pSrc -> tpixels [i ][uCol ];
9831001			const  int  i_iLeft  =  i  -  iLeft ;
984- 			r  +=  ( unsigned  char )( contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetRed (pCurSrc ) ));
985- 			g  +=  ( unsigned  char )( contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetGreen (pCurSrc ) ));
986- 			b  +=  ( unsigned  char )( contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetBlue (pCurSrc ) ));
987- 			a  +=  ( unsigned  char )( contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetAlpha (pCurSrc ) ));
1002+ 			r  +=  contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetRed (pCurSrc ));
1003+ 			g  +=  contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetGreen (pCurSrc ));
1004+ 			b  +=  contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetBlue (pCurSrc ));
1005+ 			a  +=  contrib -> ContribRow [y ].Weights [i_iLeft ] *  (double )(gdTrueColorGetAlpha (pCurSrc ));
9881006		}
989- 		pRes -> tpixels [y ][uCol ] =  gdTrueColorAlpha (r ,  g ,  b ,  a );
1007+ 		pRes -> tpixels [y ][uCol ] =  gdTrueColorAlpha (uchar_clamp ( r ),  uchar_clamp ( g ),  uchar_clamp ( b ),  uchar_clamp ( a ) );
9901008	}
9911009}
9921010
0 commit comments