Tell me, how many squares are there? Given a non-empty 2D array consisting of 0 and 1, find the number of squares whose 4 corners are all 1. The squares do not need to be "upright". All the rows are guaranteed to have the same length.

Reasonable input/output methods are allowed.

Testcases:

0001000
1000000
0000000
0000100
0100000


This returns 1.

10101
00000
10100
00000
10001


This returns 2.

1111
1111
1111
1111


This returns 20.

This is code-golf. Shortest answer in bytes wins. Standard loopholes apply.
JavaScript (ES6), 127 124 119 bytes

Saved 3 bytes thanks to nderscore

m=&gt;(F=(x,y)=&gt;m.map((r,Y)=&gt;r.map((i,X)=&gt;i?1/y?n+=x&lt;X&amp;y&lt;=Y&amp;(g=(a,b)=&gt;(m[b+X-x]||0)[a-Y+y])(x,y)&amp;g(X,Y):F(X,Y):0)))(n=0)|n


How?

This function iterates on all pairs of cells (x, y), (X, Y) of the input matrix m such that:


m[ x, y ] = m[ X, Y ] = 1
x &lt; X
y ≤ Y


Each matching pair describes the coordinates of a potential edge of a square. The inequations guarantee that each edge is tested only once.

We use the vector [ dx, dy ] = [ X - x, Y - y ] rotated 90° clockwise to test the cells located at [ x - dy, y + dx ] and [ X - dy, Y + dx ]. If they both contain a 1, we've found a valid square.



Test cases



let f =

m=&gt;(F=(x,y)=&gt;m.map((r,Y)=&gt;r.map((i,X)=&gt;i?1/y?n+=x&lt;X&amp;y&lt;=Y&amp;(g=(a,b)=&gt;(m[b+X-x]||0)[a-Y+y])(x,y)&amp;g(X,Y):F(X,Y):0)))(n=0)|n

console.log(f([
  [0,0,0,1,0,0,0],
  [1,0,0,0,0,0,0],
  [0,0,0,0,0,0,0],
  [0,0,0,0,1,0,0],
  [0,1,0,0,0,0,0]
]));

console.log(f([
  [1,0,1,0,1],
  [0,0,0,0,0],
  [1,0,1,0,0],
  [0,0,0,0,0],
  [1,0,0,0,1]
]));

console.log(f([
  [1,1,1,1],
  [1,1,1,1],
  [1,1,1,1],
  [1,1,1,1]
]));