DrawRectangle and type-casting

Why can't we put the type cast out side the loop.

int *Pixel = (int*)Row;

I mean, why do we have to typecast the row pointer every time.

if we only typecast it before the loop, does it only point to (int*) once, and then point to (char*) for the rest of the loop??


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
void drawRectangle(BitmapInfo *bmpInfo, int x, int y, int width, int height, int Color)
{
	if(x < 0)
	{
		x = 0;
	}
	if(y < 0)
	{
		y = 0;
	}
	if(width > bmpInfo->width)
	{
		width = bmpInfo->width;
	}
	if(height > bmpInfo->height)
	{
		height = bmpInfo->height;
	}

	int Pitch = bmpInfo->width * 4;

	char *Row = (char*)bmpInfo->memory + (x * 4) + (y * Pitch); 

                                              here? <--------------------------------------------------
                                                                                    
	for(int yi = y; yi < height; yi++)                                       
	{                                                                            
		int *Pixel = (int*)Row;   <-------- why doesn't it work to put this outside the loop?
		for(int xi = x; xi < width; xi++)
		{
			*Pixel++ = Color;
		}

		Row += Pitch;
	}
}

Edited by C_Worm on Reason: Initial post
Line 34 (`Row += Pitch;`) modifies what `Row` is actually pointing to, so Pixel isn't pointing to the same thing every iteration.

Edited by Joshua on
but Pixel is pointing at whatever Row is pointing to, so modifying Row should also affect Pixel??
It does not work, because Pixel++ assumes that next pixel to fill follows in memory directly afterwards. Which is not true if x != 0 or width != bitmap width.

Here's an illustration (4x4 image):
1
2
3
4
ABCD
EFGH
IJKL
MNOP


If you ask to drawRectangle with x=1, y=1, width=1, height=2, then it should fill only F and J values.
Initially you calculate Row to point to F pixel (line 22).
Then you assign Pixel pointer to same value (line 28).
Now in you do Pixel++ so it will point to G (line 31).

In case you do Row += Pitch, it will now go from F to J pixel correctly. Because Row from F pixel + Pitch is J pixel.
But in case you reuse Pixel value in next loop iteration, it will fill G pixel.

To better understand how values change, I strongly recommend you to use debugger. Set up watch window to show values of variables (Row, Pixel, Pitch, x, y, ...) and step line by line over small example (1x2 rectangel) and see how values are changing.

Edited by Mārtiņš Možeiko on
but Pixel is pointing at whatever Row is pointing to, so modifying Row should also affect Pixel??


They are pointing at the same thing, but if you change Row then they will no longer be pointing at the same thing.

Let's say we have an array of numbers where both Row and Pixel are pointing to the first element:

1
2
3
Row      v
         0  1  2  3  4  5
Pixel    ^


If we then do `Row += 1;` we get the following:

1
2
3
Row         v
         0  1  2  3  4  5
Pixel    ^
"Row" is a pointer to the first pixel to be filled in each row.
"Pixel" is a pointer to each successive pixel in that row.

Each pixel is set until the _rectangle_ "Width" is reached.
Then the "Row" pointer is incremented by the destination _bitmap_ "Pitch".

The "Row" pointer needs to be incremented by the destination bitmap's "Pitch" in the outer loop so that it points to the first pixel in each row to be filled.

The "Pixel" pointer starts at the beginning of the row to be filled by the inner loop.

One thing to keep in mind is that the width x height of the rectangle we're filling is not the same as the width x height of the destination bitmap. We're filling an arbitrary rectangle with color _within_ the destination bitmap.
It should also be noted that type-casting a pointer is just a way of telling the compiler how to interpret data located at a specific memory address and has no run-time cost.