@@ -929,27 +929,45 @@ static inline LineContribType *_gdContributionsCalc(unsigned int line_size, unsi
929
929
return res ;
930
930
}
931
931
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
+
932
950
static inline void _gdScaleRow (gdImagePtr pSrc , unsigned int src_width , gdImagePtr dst , unsigned int dst_width , unsigned int row , LineContribType * contrib )
933
951
{
934
952
int * p_src_row = pSrc -> tpixels [row ];
935
953
int * p_dst_row = dst -> tpixels [row ];
936
954
unsigned int x ;
937
955
938
956
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 ;
940
958
const int left = contrib -> ContribRow [x ].Left ;
941
959
const int right = contrib -> ContribRow [x ].Right ;
942
- int i ;
960
+ int i ;
943
961
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 ) );
953
971
}
954
972
}
955
973
@@ -982,7 +1000,7 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
982
1000
{
983
1001
unsigned int y ;
984
1002
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 ;
986
1004
const int iLeft = contrib -> ContribRow [y ].Left ;
987
1005
const int iRight = contrib -> ContribRow [y ].Right ;
988
1006
int i ;
@@ -991,12 +1009,12 @@ static inline void _gdScaleCol (gdImagePtr pSrc, unsigned int src_width, gdImag
991
1009
for (i = iLeft ; i <= iRight ; i ++ ) {
992
1010
const int pCurSrc = pSrc -> tpixels [i ][uCol ];
993
1011
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 ));
998
1016
}
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 ) );
1000
1018
}
1001
1019
}
1002
1020
0 commit comments