2121
2222Imaging
2323ImagingFill (Imaging im , const void * colour ) {
24- int x , y ;
2524 ImagingSectionCookie cookie ;
2625
2726 /* 0-width or 0-height image. No need to do anything */
2827 if (!im -> linesize || !im -> ysize ) {
2928 return im ;
3029 }
3130
31+ // xsize and ysize are invariant during the loops below.
32+ int xsize = im -> xsize ;
33+ int ysize = im -> ysize ;
34+
3235 if (im -> type == IMAGING_TYPE_SPECIAL ) {
3336 /* use generic API */
3437 ImagingAccess access = ImagingAccessNew (im );
3538 if (access ) {
36- for (y = 0 ; y < im -> ysize ; y ++ ) {
37- for (x = 0 ; x < im -> xsize ; x ++ ) {
39+ for (int y = 0 ; y < ysize ; y ++ ) {
40+ for (int x = 0 ; x < xsize ; x ++ ) {
3841 access -> put_pixel (im , x , y , colour );
3942 }
4043 }
4144 ImagingAccessDelete (im , access );
4245 } else {
4346 /* wipe the image */
44- for (y = 0 ; y < im -> ysize ; y ++ ) {
47+ for (int y = 0 ; y < ysize ; y ++ ) {
4548 memset (im -> image [y ], 0 , im -> linesize );
4649 }
4750 }
@@ -50,14 +53,16 @@ ImagingFill(Imaging im, const void *colour) {
5053 ImagingSectionEnter (& cookie );
5154 memcpy (& c , colour , im -> pixelsize );
5255 if (im -> image32 && c != 0L ) {
53- for (y = 0 ; y < im -> ysize ; y ++ ) {
54- for (x = 0 ; x < im -> xsize ; x ++ ) {
55- im -> image32 [y ][x ] = c ;
56+ for (int y = 0 ; y < ysize ; y ++ ) {
57+ // Restrict safe: sole owner of image data here.
58+ INT32 * restrict row = im -> image32 [y ];
59+ for (int x = 0 ; x < xsize ; x ++ ) {
60+ row [x ] = c ;
5661 }
5762 }
5863 } else {
5964 unsigned char cc = (unsigned char )* (UINT8 * )colour ;
60- for (y = 0 ; y < im -> ysize ; y ++ ) {
65+ for (int y = 0 ; y < ysize ; y ++ ) {
6166 memset (im -> image [y ], cc , im -> linesize );
6267 }
6368 }
@@ -70,7 +75,6 @@ ImagingFill(Imaging im, const void *colour) {
7075Imaging
7176ImagingFillLinearGradient (const ModeID mode ) {
7277 Imaging im ;
73- int y ;
7478
7579 if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I &&
7680 mode != IMAGING_MODE_L && mode != IMAGING_MODE_P ) {
@@ -82,19 +86,24 @@ ImagingFillLinearGradient(const ModeID mode) {
8286 return NULL ;
8387 }
8488
89+ // Branch on pixel type outside the loops so the compiler can tighten them.
90+ // Restrict safe: sole owner of the freshly-allocated image data here.
8591 if (im -> image8 ) {
86- for (y = 0 ; y < 256 ; y ++ ) {
92+ for (int y = 0 ; y < 256 ; y ++ ) {
8793 memset (im -> image8 [y ], (unsigned char )y , 256 );
8894 }
95+ } else if (im -> type == IMAGING_TYPE_FLOAT32 ) {
96+ for (int y = 0 ; y < 256 ; y ++ ) {
97+ FLOAT32 * restrict row = (FLOAT32 * )im -> image32 [y ];
98+ for (int x = 0 ; x < 256 ; x ++ ) {
99+ row [x ] = y ;
100+ }
101+ }
89102 } else {
90- int x ;
91- for (y = 0 ; y < 256 ; y ++ ) {
92- for (x = 0 ; x < 256 ; x ++ ) {
93- if (im -> type == IMAGING_TYPE_FLOAT32 ) {
94- IMAGING_PIXEL_FLOAT32 (im , x , y ) = y ;
95- } else {
96- IMAGING_PIXEL_INT32 (im , x , y ) = y ;
97- }
103+ for (int y = 0 ; y < 256 ; y ++ ) {
104+ INT32 * restrict row = im -> image32 [y ];
105+ for (int x = 0 ; x < 256 ; x ++ ) {
106+ row [x ] = y ;
98107 }
99108 }
100109 }
@@ -105,8 +114,6 @@ ImagingFillLinearGradient(const ModeID mode) {
105114Imaging
106115ImagingFillRadialGradient (const ModeID mode ) {
107116 Imaging im ;
108- int x , y ;
109- int d ;
110117
111118 if (mode != IMAGING_MODE_1 && mode != IMAGING_MODE_F && mode != IMAGING_MODE_I &&
112119 mode != IMAGING_MODE_L && mode != IMAGING_MODE_P ) {
@@ -118,25 +125,32 @@ ImagingFillRadialGradient(const ModeID mode) {
118125 return NULL ;
119126 }
120127
121- for (y = 0 ; y < 256 ; y ++ ) {
122- for (x = 0 ; x < 256 ; x ++ ) {
123- d = (int )sqrt (
124- (double )((x - 128 ) * (x - 128 ) + (y - 128 ) * (y - 128 )) * 2.0
125- );
126- if (d >= 255 ) {
127- d = 255 ;
128- }
129- if (im -> image8 ) {
130- im -> image8 [y ][x ] = d ;
131- } else {
132- if (im -> type == IMAGING_TYPE_FLOAT32 ) {
133- IMAGING_PIXEL_FLOAT32 (im , x , y ) = d ;
134- } else {
135- IMAGING_PIXEL_INT32 (im , x , y ) = d ;
136- }
137- }
128+ #define ASSIGN_ROW (row , y ) \
129+ for (int x = 0; x < 256; x++) { \
130+ int d = \
131+ (int)sqrt((double)((x - 128) * (x - 128) + (y - 128) * (y - 128)) * 2.0); \
132+ row[x] = d >= 255 ? 255 : d; \
133+ }
134+
135+ // Branch on pixel type outside the loops so the compiler can tighten them.
136+ // Restrict safe: sole owner of the freshly-allocated image data here.
137+ if (im -> image8 ) {
138+ for (int y = 0 ; y < 256 ; y ++ ) {
139+ UINT8 * restrict row = im -> image8 [y ];
140+ ASSIGN_ROW (row , y );
141+ }
142+ } else if (im -> type == IMAGING_TYPE_FLOAT32 ) {
143+ for (int y = 0 ; y < 256 ; y ++ ) {
144+ FLOAT32 * restrict row = (FLOAT32 * )im -> image32 [y ];
145+ ASSIGN_ROW (row , y );
146+ }
147+ } else {
148+ for (int y = 0 ; y < 256 ; y ++ ) {
149+ INT32 * restrict row = im -> image32 [y ];
150+ ASSIGN_ROW (row , y );
138151 }
139152 }
153+ #undef ASSIGN_ROW
140154
141155 return im ;
142156}
0 commit comments