@@ -919,27 +919,45 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
919
919
return res ;
920
920
}
921
921
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
+
922
940
static inline void _gdScaleRow (gdImagePtr pSrc , unsigned int src_width , gdImagePtr dst , unsigned int dst_width , unsigned int row , LineContribType * contrib )
923
941
{
924
942
int * p_src_row = pSrc -> tpixels [row ];
925
943
int * p_dst_row = dst -> tpixels [row ];
926
944
unsigned int x ;
927
945
928
946
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 ;
930
948
const int left = contrib -> ContribRow [x ].Left ;
931
949
const int right = contrib -> ContribRow [x ].Right ;
932
- int i ;
950
+ int i ;
933
951
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 ) );
943
961
}
944
962
}
945
963
@@ -972,7 +990,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
972
990
{
973
991
unsigned int y ;
974
992
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 ;
976
994
const int iLeft = contrib -> ContribRow [y ].Left ;
977
995
const int iRight = contrib -> ContribRow [y ].Right ;
978
996
int i ;
@@ -981,12 +999,12 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
981
999
for (i = iLeft ; i <= iRight ; i ++ ) {
982
1000
const int pCurSrc = pSrc -> tpixels [i ][uCol ];
983
1001
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 ));
988
1006
}
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 ) );
990
1008
}
991
1009
}
992
1010
0 commit comments