For each row of the image,
Add up the N consecutive pixels, so you get W - N + 1 pixels.
For each column of the new image,
For each consecutive sequence of N pixels, (H - N + 1)
Add them up and compare to the current best.
To add up each consecutive sequence of pixels, you could subtract the last pixel, and add the next pixel.
You could also reuse the image array as storage, if it can be modified. If not, a memory-optimization would be to just store the latest column, and go trough it for each step in the first loop.
Runtime: O(w·h)
Here is some code in C#, to demonstrate this (ignoring the pixel format, and any potential overflows):
List<Point> FindBrightestSquare(int[,] image, int N, out int squareSum)
{
int width = image.GetLength(0);
int height = image.GetLength(1);
if (width < N || height < N)
{
return false;
}
int currentSum;
for (int y = 0; y < height; y++)
{
currentSum = 0;
for (int x = 0; x < width; x++)
{
currentSum += image[x,y];
if (x => N)
{
currentSum -= image[x-N,y];
image[x-N,y] = currentSum;
}
}
}
int? bestSum = null;
List<Point> bestCandidates = new List<Point>();
for (int x = 0; x <= width-N; x++)
{
currentSum = 0;
for (int y = 0; y < height; y++)
{
currentSum += image[x,y];
if (y >= N)
{
currentSum -= image[x, y-N];
if (bestSum == null || currentSum > bestSum)
{
bestSum = currentSum;
bestCandidates.Clear();
bestCandidates.Add(new Point(x, y-N));
}
else if (currentSum == bestSum)
{
bestCandidates.Add(new Point(x, y-N));
}
}
}
}
squareSum = bestSum.Value;
return bestCandidates;
}