@@ -25,29 +25,39 @@ typedef struct {
2525 const void * table ;
2626} im_point_context ;
2727
28+ /**
29+ * Contract: imIn is read-only and imOut must be a distinct image.
30+ */
2831static void
2932im_point_8_8 (Imaging imOut , Imaging imIn , im_point_context * context ) {
30- int x , y ;
3133 /* 8-bit source, 8-bit destination */
3234 UINT8 * table = (UINT8 * )context -> table ;
33- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
34- UINT8 * in = imIn -> image8 [y ];
35- UINT8 * out = imOut -> image8 [y ];
36- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
35+ // Invariant over the loop.
36+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
37+ for (int y = 0 ; y < ysize ; y ++ ) {
38+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
39+ UINT8 * restrict in = imIn -> image8 [y ];
40+ UINT8 * restrict out = imOut -> image8 [y ];
41+ for (int x = 0 ; x < xsize ; x ++ ) {
3742 out [x ] = table [in [x ]];
3843 }
3944 }
4045}
4146
47+ /**
48+ * Contract: imIn is read-only and imOut must be a distinct image.
49+ */
4250static void
4351im_point_2x8_2x8 (Imaging imOut , Imaging imIn , im_point_context * context ) {
44- int x , y ;
4552 /* 2x8-bit source, 2x8-bit destination */
4653 UINT8 * table = (UINT8 * )context -> table ;
47- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
48- UINT8 * in = (UINT8 * )imIn -> image [y ];
49- UINT8 * out = (UINT8 * )imOut -> image [y ];
50- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
54+ // Invariant over the loop.
55+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
56+ for (int y = 0 ; y < ysize ; y ++ ) {
57+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
58+ UINT8 * restrict in = (UINT8 * )imIn -> image [y ];
59+ UINT8 * restrict out = (UINT8 * )imOut -> image [y ];
60+ for (int x = 0 ; x < xsize ; x ++ ) {
5161 out [0 ] = table [in [0 ]];
5262 out [3 ] = table [in [3 ] + 256 ];
5363 in += 4 ;
@@ -56,15 +66,20 @@ im_point_2x8_2x8(Imaging imOut, Imaging imIn, im_point_context *context) {
5666 }
5767}
5868
69+ /**
70+ * Contract: imIn is read-only and imOut must be a distinct image.
71+ */
5972static void
6073im_point_3x8_3x8 (Imaging imOut , Imaging imIn , im_point_context * context ) {
61- int x , y ;
6274 /* 3x8-bit source, 3x8-bit destination */
6375 UINT8 * table = (UINT8 * )context -> table ;
64- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
65- UINT8 * in = (UINT8 * )imIn -> image [y ];
66- UINT8 * out = (UINT8 * )imOut -> image [y ];
67- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
76+ // Invariant over the loop.
77+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
78+ for (int y = 0 ; y < ysize ; y ++ ) {
79+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
80+ UINT8 * restrict in = (UINT8 * )imIn -> image [y ];
81+ UINT8 * restrict out = (UINT8 * )imOut -> image [y ];
82+ for (int x = 0 ; x < xsize ; x ++ ) {
6883 out [0 ] = table [in [0 ]];
6984 out [1 ] = table [in [1 ] + 256 ];
7085 out [2 ] = table [in [2 ] + 512 ];
@@ -74,15 +89,20 @@ im_point_3x8_3x8(Imaging imOut, Imaging imIn, im_point_context *context) {
7489 }
7590}
7691
92+ /**
93+ * Contract: imIn is read-only and imOut must be a distinct image.
94+ */
7795static void
7896im_point_4x8_4x8 (Imaging imOut , Imaging imIn , im_point_context * context ) {
79- int x , y ;
8097 /* 4x8-bit source, 4x8-bit destination */
8198 UINT8 * table = (UINT8 * )context -> table ;
82- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
83- UINT8 * in = (UINT8 * )imIn -> image [y ];
84- UINT8 * out = (UINT8 * )imOut -> image [y ];
85- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
99+ // Invariant over the loop.
100+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
101+ for (int y = 0 ; y < ysize ; y ++ ) {
102+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
103+ UINT8 * restrict in = (UINT8 * )imIn -> image [y ];
104+ UINT8 * restrict out = (UINT8 * )imOut -> image [y ];
105+ for (int x = 0 ; x < xsize ; x ++ ) {
86106 out [0 ] = table [in [0 ]];
87107 out [1 ] = table [in [1 ] + 256 ];
88108 out [2 ] = table [in [2 ] + 512 ];
@@ -93,29 +113,39 @@ im_point_4x8_4x8(Imaging imOut, Imaging imIn, im_point_context *context) {
93113 }
94114}
95115
116+ /**
117+ * Contract: imIn is read-only and imOut must be a distinct image.
118+ */
96119static void
97120im_point_8_32 (Imaging imOut , Imaging imIn , im_point_context * context ) {
98- int x , y ;
99121 /* 8-bit source, 32-bit destination */
100122 char * table = (char * )context -> table ;
101- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
102- UINT8 * in = imIn -> image8 [y ];
103- INT32 * out = imOut -> image32 [y ];
104- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
123+ // Invariant over the loop.
124+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
125+ for (int y = 0 ; y < ysize ; y ++ ) {
126+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
127+ UINT8 * restrict in = imIn -> image8 [y ];
128+ INT32 * restrict out = imOut -> image32 [y ];
129+ for (int x = 0 ; x < xsize ; x ++ ) {
105130 memcpy (out + x , table + in [x ] * sizeof (INT32 ), sizeof (INT32 ));
106131 }
107132 }
108133}
109134
135+ /**
136+ * Contract: imIn is read-only and imOut must be a distinct image.
137+ */
110138static void
111139im_point_32_8 (Imaging imOut , Imaging imIn , im_point_context * context ) {
112- int x , y ;
113140 /* 32-bit source, 8-bit destination */
114141 UINT8 * table = (UINT8 * )context -> table ;
115- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
116- INT32 * in = imIn -> image32 [y ];
117- UINT8 * out = imOut -> image8 [y ];
118- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
142+ // Invariant over the loop.
143+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
144+ for (int y = 0 ; y < ysize ; y ++ ) {
145+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
146+ INT32 * restrict in = imIn -> image32 [y ];
147+ UINT8 * restrict out = imOut -> image8 [y ];
148+ for (int x = 0 ; x < xsize ; x ++ ) {
119149 int v = in [x ];
120150 if (v < 0 ) {
121151 v = 0 ;
@@ -202,43 +232,53 @@ ImagingPoint(Imaging imIn, ModeID mode, const void *table) {
202232 );
203233}
204234
235+ /**
236+ * Apply an affine (scale/offset) transform to every pixel of imIn,
237+ * returning a newly allocated result.
238+ *
239+ * Contract: imIn is read-only.
240+ */
205241Imaging
206242ImagingPointTransform (Imaging imIn , double scale , double offset ) {
207243 /* scale/offset transform */
208244
209245 ImagingSectionCookie cookie ;
210246 Imaging imOut ;
211- int x , y ;
212247
213248 if (!imIn || (imIn -> mode != IMAGING_MODE_I && imIn -> mode != IMAGING_MODE_I_16 &&
214249 imIn -> mode != IMAGING_MODE_F )) {
215250 return (Imaging )ImagingError_ModeError ();
216251 }
217252
218- imOut = ImagingNew (imIn -> mode , imIn -> xsize , imIn -> ysize );
253+ // Invariant over the loops.
254+ int xsize = imIn -> xsize , ysize = imIn -> ysize ;
255+
256+ imOut = ImagingNew (imIn -> mode , xsize , ysize );
219257 if (!imOut ) {
220258 return NULL ;
221259 }
222260
223261 switch (imIn -> type ) {
224262 case IMAGING_TYPE_INT32 :
225263 ImagingSectionEnter (& cookie );
226- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
227- INT32 * in = imIn -> image32 [y ];
228- INT32 * out = imOut -> image32 [y ];
264+ for (int y = 0 ; y < ysize ; y ++ ) {
265+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
266+ INT32 * restrict in = imIn -> image32 [y ];
267+ INT32 * restrict out = imOut -> image32 [y ];
229268 /* FIXME: add clipping? */
230- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
269+ for (int x = 0 ; x < xsize ; x ++ ) {
231270 out [x ] = in [x ] * scale + offset ;
232271 }
233272 }
234273 ImagingSectionLeave (& cookie );
235274 break ;
236275 case IMAGING_TYPE_FLOAT32 :
237276 ImagingSectionEnter (& cookie );
238- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
239- FLOAT32 * in = (FLOAT32 * )imIn -> image32 [y ];
240- FLOAT32 * out = (FLOAT32 * )imOut -> image32 [y ];
241- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
277+ for (int y = 0 ; y < ysize ; y ++ ) {
278+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
279+ FLOAT32 * restrict in = (FLOAT32 * )imIn -> image32 [y ];
280+ FLOAT32 * restrict out = (FLOAT32 * )imOut -> image32 [y ];
281+ for (int x = 0 ; x < xsize ; x ++ ) {
242282 out [x ] = in [x ] * scale + offset ;
243283 }
244284 }
@@ -247,11 +287,12 @@ ImagingPointTransform(Imaging imIn, double scale, double offset) {
247287 case IMAGING_TYPE_SPECIAL :
248288 if (imIn -> mode == IMAGING_MODE_I_16 ) {
249289 ImagingSectionEnter (& cookie );
250- for (y = 0 ; y < imIn -> ysize ; y ++ ) {
251- char * in = (char * )imIn -> image [y ];
252- char * out = (char * )imOut -> image [y ];
290+ for (int y = 0 ; y < ysize ; y ++ ) {
291+ // restrict safe: imIn is read-only, imOut is a fresh allocation.
292+ char * restrict in = imIn -> image [y ];
293+ char * restrict out = imOut -> image [y ];
253294 /* FIXME: add clipping? */
254- for (x = 0 ; x < imIn -> xsize ; x ++ ) {
295+ for (int x = 0 ; x < xsize ; x ++ ) {
255296 UINT16 v ;
256297 memcpy (& v , in + x * sizeof (v ), sizeof (v ));
257298 v = v * scale + offset ;
0 commit comments