Thanks again.
Ok, finally finished a 'working' version , what I ended up doing was similar to the original idea above.
Pick a starting square.
scan along x to find the max possible range. (maxX)
scan along y to find the maximum possible range. (maxY)
brute force test each possible rectangles from (maxX , maxY) to (1,1) to see which had the largest valid area (where all squares are of the correct type and are unprocessed).
mark all the squares under that rectangle as processed.
repeat for next valid square through the grid.
It ended up being a little more complicated then I'd originally planned but it works nicely with L-shaped section and other oddities.
I can probably make a few optimisations on it now it's stable but it processes quickly for my largest levels so am not too worried.
Thanks again for the help.