No it's not looping through the data backwards. It starts at the beginning of data, and indexes up.
As you can see, here the pointer "blocks" is advanced past "data" already. It points "nblocks" past the beginning of data.
const uint32_t * blocks = (const uint32_t *)(data + nblocks*4);
So, you need a negative index to get to the beginning of data (-nblocks). The start of data is precisely at "blocks[-nblocks]". The "for" loop simply starts there, and counts up.
for(i = -nblocks; i; i++)